TL; DR: un tipo leggermente più restrittivo di distanza di modifica, in cui possiamo solo inserire ed eliminare singoli caratteri, può essere calcolato in tempo linearitmico quando entrambe (o anche solo una) delle stringhe hanno caratteri univoci. Ciò fornisce utili limiti superiore e inferiore sulla distanza di modifica di Levenshtein.
Inserisci / elimina la distanza di modifica e le sottosequenze comuni più lunghe
La distanza di modifica di Levenshtein consente inserimenti, eliminazioni e sostituzioni a carattere singolo, assegnando a ciascuno un costo di 1. Se ci limitiamo a soli inserimenti ed eliminazioni, otteniamo una misura di distanza simile che ora fa sì che le sostituzioni abbiano un costo di 2 (poiché qualsiasi sostituzione può essere imitato usando un inserimento e una cancellazione). Non conosco un nome standard per questo tipo più restrittivo di distanza di modifica, quindi lo chiamerò "inserisci / elimina distanza di modifica". Corrisponde strettamente al problema della sottosequenza comune più lunga (LCS) , in cui ci vengono date due stringhe, rispettivamente di lunghezza e , e vogliamo conoscere la lunghezza della sottosequenza più lunga che appare in entrambi. Se due stringhe hanno LCSn L n + m - 2 LmnL, quindi hanno inserire / eliminare la modifica della distanzan+m−2L : il modo più semplice per vederlo è allineare le stringhe in modo che i caratteri nell'LCS appaiano uno sopra l'altro, mentre i caratteri non nell'LCS appaiono di fronte a uno -
spazio personaggio. Sarà quindi evidente che possiamo modificare la prima stringa nella seconda effettuando un inserimento ovunque sia presente un -
nella riga superiore e una cancellazione ovunque ci sia un -
nella riga inferiore. Per esempio:
-C-IRC-LE
T-RI-CKLE
Qui l'LCS di CIRCLE
e TRICKLE
, ICLE
ha lunghezza 4 e la distanza di modifica è effettivamente .6+7−2∗4=5
Sottosequenze crescenti più lunghe
Il motivo di questa deviazione è che esiste un modo molto efficiente per calcolare l'LCS (e quindi l'inserimento / eliminazione della distanza di modifica) quando almeno una delle sequenze contiene solo caratteri distinti: in questo caso, il problema LCS può essere trasformato in il problema di trovare una sottosequenza crescente più lunga , che può essere risolta nel tempo . Supponiamo di avere due stringhe e e che la stringa abbia caratteri distinti. Possiamo rinominare il primo carattere in a 1, il secondo in 2 e così via, tenendo traccia del numero assegnato a ciascun personaggio in una tabella. Quindi inA B A A B O ( n + m registro m ) A B n mO(nlogn)ABAAB, rinominiamo i suoi caratteri usando questa tabella (ad esempio, ogni ricorrenza di qualunque sia stato il primo carattere A
è cambiata in 1, ecc.). Infine, cerchiamo una sottosequenza crescente più lunga in B
. Ciò corrisponde a un LCS tra A
e B
, e da lì possiamo immediatamente calcolare l'inserimento / eliminazione della distanza di modifica. Il tempo totale necessario è solo se e hanno rispettivamente lunghezze e .O(n+mlogm)ABnm
Limiti sulla distanza di modifica di Levenshtein
La distanza di inserimento / cancellazione fornisce chiaramente un limite superiore sulla distanza di Levenshtein (poiché qualsiasi sequenza valida di operazioni di modifica sotto la distanza di inserimento / cancellazione è anche una sequenza valida di operazioni di modifica di Levenshtein). Dividere la distanza di modifica in insert / delete per 2 dà anche un limite inferiore, poiché nel caso peggiore qualsiasi operazione di modifica in Levenshtein può essere cambiata in 2 operazioni di modifica in insert / delete.
generalizzazioni
Già nel 1977, Hunt e Szymanski hanno escogitato un algoritmo che può essere visto come una generalizzazione dell'algoritmo di sottosezione in aumento più lungo. È efficiente quando il numero di coppie di posizioni di caratteri corrispondenti tra le due stringhe è piccolo. Se ci sono coppie di questo tipo, il loro algoritmo richiede tempo . (Si noti che se tutti i caratteri in una stringa sono distinti.) Questo algoritmo era la base del programma originale , che trattava intere righe di testo come singoli caratteri. in seguito è passato all'uso dell'algoritmo -time di Myers , doveO ( ( r + n ) log n ) r ≤ n O ( n d ) drO((r+n)logn)r≤ndiff
diff
O(nd)d è la distanza di modifica di inserimento / eliminazione, poiché si comporta meglio quando le differenze complessive sono piccole ma alcuni "caratteri" (righe di testo) appaiono frequentemente (come una riga contenente solo una parentesi graffa di apertura nel codice del programma C).
Hunt, J .; Szymanski, T. (1977), "Un algoritmo veloce per il calcolo delle sottosequenze comuni più lunghe", Communications of the ACM, 20 (5): 350–353, doi: 10.1145 / 359581.359603