Le problème devient plus facile, si l'on considère les suppressions longues et la copie de sous-chaînes au lieu de transpositions. Supposons que nous utilisons l'algorithme de programmation dynamique standard pour éditer le calcul de distance, et qu'une opération coûteuse de longueur augmente la distance de a k + b , pour certaines constantes a , b ≥ 0 . Ces constantes peuvent être différentes pour les suppressions longues et la copie de sous-chaîne.kak+ba,b≥0
Une longue suppression est la suppression d'une sous-chaîne arbitraire de . Les soutenir est facile, si nous les décomposons en deux types d'opérations simples: supprimer le premier caractère (coût a + b ) et étendre la suppression d'un caractère (coût a ). En plus du tableau standard A , où A [ i , j ] est la distance d'édition entre les préfixes x [ 1 … i ] et y [ 1 … j ] , nous utilisons un autre tableau A dxa+baAA[i,j]x[1…i]y[1…j]Adpour stocker la distance d'édition, lorsque la dernière opération utilisée était une longue suppression. Avec ce tableau, il suffit de regarder , A [ i - 1 , j - 1 ] , A [ i , j - 1 ] et A d [ i - 1 , j ] lors du calcul A [ i , j ] et A dA[i−1,j]A[i−1,j−1]A[i,j−1]Ad[i−1,j]A[i,j] ) . , nous permettant de le faire en O ( 1Ad[i,j]O ( 1 )
La copie de sous-chaîne signifie l'insertion d'une sous-chaîne arbitraire de dans la chaîne éditée. Comme pour les suppressions longues, nous décomposons l'opération en deux opérations simples: l'insertion du premier caractère et l'extension de l'insertion d'un caractère. Nous utilisons également le tableau A sXUNEs pour stocker la distance d'édition entre les préfixes, à condition que la dernière opération utilisée soit la copie de la sous-chaîne.
Faire cela efficacement est plus compliqué qu'avec de longues suppressions, et je ne sais pas si nous pouvons arriver à temps amorti par cellule. Nous construisons un arbre de suffixe pour x , ce qui prend du temps O ( | x | ) , en supposant un alphabet de taille constante. Nous stockons un pointeur sur le nœud d'arbre de suffixe courant dans A s [ i , j - 1 ] , ce qui nous permet de vérifier en temps constant, si nous pouvons étendre l'insertion par le caractère y [ j ] . Si cela est vrai, nous pouvons calculerO ( 1 )XO ( | x | )UNEs[ i , j - 1 ]y[ j ] ] en temps constant.A [ i , j ]et UNEs[ i , j ]
Sinon, , où z est la sous-chaîne insérée qui a été utilisée pour calculer A s [ i , j - 1 ] , n'est pas une sous-chaîne de x . Nous utilisons l'arbre des suffixes pour trouver le suffixe le plus long z ′ de z , pour lequel z ′ y [ j ] est une sous-chaîne de x , dans O ( | z | - | z ′ | )zy[ j ]zUNEs[ i , j - 1 ]Xz′zz′y[ j ]XO ( | z| - | z′| ) . Pour calculer , nous devons maintenant regarder les cellules A [ i , j - | z ′ | - 1 ] à A [ i , j - 1 ] . Trouver le suffixe z ' nécessite juste un temps O ( 1 ) amortipar cellule, mais le calcul de A s [ i , j ] avec une approche par force brute prend O ( | zUNEs[ i , j ]A [ i , j - | z′| -1]A [ i , j - 1 ]z′O ( 1 )UNEs[ i , j ] temps. Il existe probablement un moyen de le faire plus efficacement, mais je ne le trouve pas pour le moment.O ( | z′| )
Dans le pire des cas, l'algorithme prend temps, mais une meilleure analyse devrait être possible. La distance d'édition résultante avec de longues suppressions et la copie de sous-chaîne n'est pas symétrique, mais cela ne devrait pas être un problème. Après tout, il est généralement plus facile d'atteindre la chaîne vide à partir d'une chaîne non vide que l'inverse.O ( min ( | x | ⋅ | y|2, | x |2⋅ | y| ))