Étant donné une chaîne , je voudrais trouver la sous-séquence répétée la plus longue (au moins deux fois). Autrement dit, je voudrais trouver une chaîne qui est une sous-séquence (ne doit pas nécessairement être contiguë) de telle que . Autrement dit, w est une chaîne dont les moitiés apparaissent deux fois de suite. Notez que w est une sous-séquence de s , mais pas nécessairement une sous-chaîne.w s w = w ′ ⋅ w ′ w w s
Exemples:
Pour 'ababccabdc', ce sera 'abcabc', car 'abc' = 'abc' et 'abc' apparaît (au moins) deux fois dans 'ababccabdc'.
Pour 'addbacddabcd', une option est 'dddd' parce que 'dd' apparaît deux fois (je ne peux pas utiliser la même lettre plusieurs fois, mais ici j'ai 4 'd's donc c'est ok), mais c'est lebngth 4. Je peux en trouver une meilleure de longueur 8: 'abcdabcd', car 'abcd' est une sous-chaîne de 'addbacddabcd' qui apparaît deux fois.
Je suis intéressé à trouver la sous-séquence répétée la plus longue. Ceci est également appelé "recherche du carré le plus long / le plus grand", mais j'ai lu de nombreux articles dans lesquels un carré est défini pour une sous-chaîne et non pour une sous-séquence.
Je peux facilement utiliser un algorithme de force brute qui prendra en itérant sur toutes les options pour un point d'arrêt dans la chaîne, puis j'aurai deux chaînes dans lesquelles je rechercherai la sous-séquence commune la plus longue / la plus longue, mais chaque vérification prendra utilisant une technique de programmation dynamique, donc tout le temps sera . J'ai trouvé un algorithme plus efficace pour la sous-séquence commune la plus longue qui prend O (\ frac {n ^ 2} {\ log n}) , donc le temps d'exécution sera O (\ frac {n ^ 3} {\ log n}) .O ( n 2 ) O ( n 3 )O(n3
Je recherche un algorithme plus efficace pour le problème de sous-séquence répétitif le plus long. Peut-être que mon idée d'itérer sur tous les points d'arrêt fait perdre trop de temps et peut être réduite à moins d'itérations. Ou peut-être qu'un algorithme avec une attitude différente peut résoudre ce problème.
J'ai cherché dans de nombreuses revues et questions précédentes, et la plupart des résultats que j'ai trouvés concernaient une sous-chaîne et non une sous-séquence.
J'ai également lu que cela peut être fait en utilisant des arbres de suffixes, mais cela était également pertinent pour les sous-chaînes et je ne suis pas sûr si une telle idée peut être étendue pour la sous-séquence.
Je recherche une solution qui s'exécute dans le temps . S'il existe un dans le temps ce sera encore mieux (je ne suis pas sûr que cela existe).O ( n ⋅ log n )
$
Réponses:
Voici une solution de programmation dynamique.
Supposons que la chaîne d'entrée soit . Créez une table dont les lignes et les colonnes sont indexées par (où est la longueur de la chaîne), remplies par la règle La réponse est . T 0 , … , n n T [ i , j ] = { 0 si i = 0 ou j = 0 , T [ i - 1 , j - 1 ] + 1 si x i = x j et i ≠ j , max ( T [ i - 1X1… Xn T 0 , … , n n
la source
if
dp[i][j] = dp[i - 1][j - 1] + 1