Je me demande si quelqu'un connaît l'algorithme (optimal?) pour une sous-chaîne de sous-chevaucheuse récurrente la plus longue. P>
Par exemple, dans la chaîne p>
abadzedgbadez p>
Le plus long récurrent serait "mauvais". Incidemment, s'il n'y a pas de tel résultat, l'algorithme devrait alerter qu'une telle chose s'est produite. Je suppose que cela implique suffixe des arbres. P>
Je suis sûr que cela doit exister déjà quelque part. Merci pour l'aide! P>
4 Réponses :
Puisque vous l'appliquez sur la musique, vous ne recherchez probablement pas de matchs à 100%; Il y aura attendu des divergences d'une instance du thème à un autre. Vous pouvez essayer d'utiliser des algorithmes d'analyse de séquence de gènes - il y a beaucoup de cette variété de choses qui y vont. Essayez de souffler ou d'autres algorithmes d'alignement. P>
Vous pouvez également essayer la famille des algorithmes WinerpiPi, ainsi que diverses implémentations de préfixes de cet ensemble de résultats spécifique (ces résultats permettent des lacunes dans la sous-chaîne; par exemple, ABCID et AFBCD contiennent tous deux ABCD). En fait, j'ai un papier sur un algorithme qui pourrait être intéressant si vous seriez intéressé; J'aurais besoin d'atteindre l'autorisation de distribution, alors faites le moi savoir. P>
Notez que c'est en fait un sujet très compliqué (à faire efficacement) pour de grands ensembles de données. P>
Source: recherche depuis un an ou deux sur un sujet comparable (détection à thème). P>
Si vous pouviez me donner accès, cela serait apprécié!
Je pense qu'il applique ceci aux paroles, alors je pense qu'il recherche 100% des matchs.
@Brandon - J'ai demandé la permission, je vais voir ce que je peux faire. @ las3rjock - pas vraiment. Par exemple: j'étais un homme idiot que j'étais stupide, exemple de l'homme à thème: la bombe passée. Les chaînes ne sont pas une correspondance exacte. De plus, beaucoup de paroles ont une ponctuation différente et ce que rien. Donc, je ne suis pas sûr qu'il recherche une correspondance exacte.
BAH Mise en forme. Exemple était "J'étais un homme idiot" Versus "J'étais stupide, homme"
@Brandon - s'avère qu'il n'y a pas de clauses de distribution, donc je posterai un lien ce soir :)
Ouais, à propos de la chose des paroles. Je parle de classifier littéralement la musique par des notes. Cela n'a rien à voir avec les paroles. Vous pouvez transcoder des notes musicales dans une chaîne de symboles. Merci d'avoir vérifié les droits de distribution! =]
Suffix Array est une bonne structure de données pour résoudre ce problème. P>
Il existe une solution à ce problème dans Programmation des perles < / a> par Jon Bentley. P>
@NICK Je ne pense pas que la même solution dans la programmation de perles peut être directement appliquée ici. L'exemple de "banane" donne "Ana" qui survient deux fois et se chevauche donc, contrairement à la condition mentionnée par OP. Une certaine modification peut être nécessaire pour des conditions non superposées. Que dis-tu?
@Abhijeetkashnia, tu as raison. Peut-être pouvons-nous résoudre ce problème si nous veillons à ce que la comparaison des éléments adjacents s'arrête lorsque le caractère décalage de chevauchement, au lieu de comparer les chaînes entières.
Un simple algorithme est de le faire: p>
(comme l'autre réponse vient de poster indique, je décris un ensemble de suffixe ici.) P>
Ceci est encore plutôt brutal. Je me demande s'il y a une approche légèrement plus élégante? Je crois qu'une approche arborée préserverait les informations structurelles et fournirait une sorte d'informations de profondeur pouvant être rapidement traversée pour fournir des informations de longueur les plus longues.
Avec un type approprié - voir l'article du suffixe Wikipedia - L'heure de fonctionnement est O (n journalisation) dans le pire des cas et généralement mieux. L'itération est O (n), il est donc dominé par le tri des coûts de tri. La force brute évidente sera du moins (n ^ 2) au moins (comparant chaque paire possible). Les arbres de construction vont probablement coûter beaucoup plus de mémoire, ce qui aura des effets néfastes réels sur la performance (considérer le cache, etc.).
D'accord, voici une idée folle.
Créer une fonction qui détermine s'il existe une sous-chaîne récurrente de la longueur K dans O (n) (où N est la longueur du texte). Cela peut être fait en utilisant un hachage roulant (voir Wikipedia pour RABIN-KARP STRING ALGORITHM A >) Pour générer tous les n hachages en temps linéaire et utiliser une hache / BST (ou une carte ou une carte dict ou quelle que soit votre langue l'appelle) pour stocker les positions de sous-chaînes correspondantes. Avant d'insérer le hachage actuel à la structure de données, nous vérifions si nous l'avons déjà vu auparavant. Si cela a été vu auparavant, nous recherchons simplement les indices où ce hachage a été généré et voyez si la sous-chaîne correspondante est une correspondance non chevauchante. P> Maintenant que nous pouvons trouver une sous-chaîne de la duque à O (n ) Temps, nous exécutons simplement une recherche binaire pour trouver le plus grand K pour lequel nous pouvons trouver une correspondance de substration non chevauchante à l'aide de notre fonction. P> code dans Python suit P> A=23
MOD=10007 # use a random value in the real world
def hsh(text):
return sum([ord(c)*A**(len(text)-i-1) for i,c in enumerate(text)])%MOD
def k_substring(text, k):
substrings={}
cur=hsh(text[:k])
pwr=(A**(k-1))%MOD
substrings[cur]=[0]
for i in xrange(k,len(text)):
to_remove=(ord(text[i-k])*pwr)%MOD
to_add=ord(text[i])
cur-=to_remove
if cur<0:
cur+=MOD
cur=(cur*A)%MOD
cur=(cur+to_add)%MOD
if cur in substrings:
lst=substrings[cur]
for index in lst:
if index+k<=i-k+1 and text[index:index+k]==text[i-k+1:i+1]:
return index
lst.append(i-k+1)
else:
substrings[cur]=[i-k+1]
return -1
def longest_substring(text):
hi,lo=len(text),0
while hi>lo:
mid=(hi+lo+1)>>1
if k_substring(text,mid)==-1:
hi=mid-1
else:
lo=mid
index=k_substring(text,lo)
return text[index:index+lo]
Juste curieux - Quelle est la demande d'entreprise pour cela?
Ce n'est pas une application commerciale. Il est lié à la recherche du thème dans une chanson et est plus un curio pour le moment jusqu'à ce que je reçoive un projet impliquant cela. =]