Il problema diventa più semplice se si considerano lunghe eliminazioni e copie di sottostringhe anziché trasposizioni. Supponiamo che stiamo usando l'algoritmo di programmazione dinamica standard per il calcolo della modifica della distanza e che un'operazione costosa di lunghezza aumenta la distanza di a k + b , per alcune costanti a , b ≥ 0kak+ba,b≥0 . Queste costanti possono essere diverse per le lunghe eliminazioni e la copia di sottostringhe.
Una lunga cancellazione è la cancellazione di una sottostringa arbitraria da . Supportarli è facile, se li suddividiamo in due tipi di semplici operazioni: eliminare il primo carattere (costo a + b ) ed estendere la cancellazione di un carattere (costo a ). Oltre alla matrice standard A , dove A [ i , j ] è la distanza di modifica tra i prefissi x [ 1 ... i ] e y [ 1 ... j ] , utilizziamo un'altra matrice Axa+baAA[i,j]x[1…i]y[1…j]Adper memorizzare la distanza di modifica, quando l'ultima operazione utilizzata è stata una lunga eliminazione. Con questo array, dobbiamo solo guardare , A [ i - 1 , j - 1 ] , A [ i , j - 1 ] e A d [ i - 1 , j ] durante il calcolo A [ i , j ] e A d [ iA[i−1,j]A[i−1,j−1]A[i,j−1]Ad[i−1,j]A[i,j] , permettendoci di farlo in O ( 1 ) volta.Ad[i,j]O(1)
Copia sottostringa significa l'inserimento di una sottostringa arbitraria di nella stringa modificata. Come per le lunghe eliminazioni, suddividiamo l'operazione in due semplici operazioni: l'inserimento del primo carattere e l'estensione dell'inserimento di un carattere. Usiamo anche serie A s per memorizzare la distanza di montaggio tra i prefissi, a condizione che l'ultima operazione è stata utilizzata sottoStringa copiare.xAs
Fare questo in modo efficiente è più complicato che con le lunghe eliminazioni, e non sono sicuro che si possa arrivare al tempo ammortizzato per cella. Costruiamo un albero di suffissi per x , che richiede tempo O ( | x | ) , assumendo un alfabeto di dimensioni costanti. Memorizziamo un puntatore al nodo dell'albero del suffisso corrente in A s [ i , j - 1 ] , permettendoci di verificare in tempo costante se possiamo estendere l'inserimento con il carattere y [ j ] . Se questo è vero, possiamo calcolare A [ iO(1)xO(|x|)As[i,j−1]y[j]A[i,j]e As[i,j] in tempo costante.
Altrimenti , dove z è la sottostringa inserita che è stata utilizzata per calcolare A s [ i , j - 1 ] , non è una sottostringa di x . Usiamo l'albero dei suffissi per trovare il suffisso più lungo z ′ di z , per cui z ′ y [ j ] è una sottostringa di x , nel tempo O ( | z | - | z ′ | ) . Calcolarezy[j]zAs[i,j−1]xz′zz′y[j]xO(|z|−|z′|) , ora dobbiamo guardare le celle A [ i , j - | z ′ | - 1 ] a A [ i , j - 1 ] . Trovare il suffisso z ′ richiede solo il tempo O ( 1 ) ammortizzatoper cella, ma calcolare A s [ i , j ] con un approccio a forza bruta richiede O ( | zAs[i,j]A[i,j−|z′|−1]A[i,j−1]z′O(1)As[i,j]O(|z′|) tempo. Probabilmente c'è un modo per farlo in modo più efficiente, ma non riesco a trovarlo in questo momento.
Nel peggiore dei casi, l'algoritmo richiede , ma dovrebbe essere possibile un'analisi migliore. La distanza di modifica risultante con lunghe eliminazioni e copia di sottostringhe non è simmetrica, ma ciò non dovrebbe costituire un problema. Dopotutto, di solito è più facile raggiungere la stringa vuota da una non vuota rispetto al contrario.O(min(|x|⋅|y|2,|x|2⋅|y|))