Después de aprender a construir una matriz de sufijos en complejidad , estoy interesado en descubrir las aplicaciones de las matrices de sufijos. Una de ellas es encontrar la subcadena común más larga entre dos cadenas, en el tiempo . Encontré en internet el siguiente algoritmo:
- fusionar las dos cadenas y en una cadena
- calcular la matriz de sufijos de
- calcular la matriz (prefijo común más largo)
- la respuesta es el mayor valor
Traté de implementarlo, pero como no se dijeron muchos detalles de implementación (es decir, al concatenar las cadenas, ¿debería poner un carácter especial entre ellas ( )?), Mi código falló en muchos casos de prueba. ¿Alguien podría elaborar más sobre este algoritmo?
Gracias por adelantado.
Nota: no garantizo la exactitud de este algoritmo; Lo encontré en un blog y no estoy seguro de que funcione. Si cree que es incorrecto, sugiera otro algoritmo.
algorithms
suffix-array
Rontogiannis Aristofanis
fuente
fuente
Respuestas:
Tu algoritmo es incorrecto . Supongo que sabe cómo calcular la matriz de sufijos y la matriz LCP de una cadena, es decir, su implementación eficiente. Como se ha señalado en los comentarios, debe intentar comprender qué es cada componente y por qué funciona.
En primer lugar, es la matriz de sufijos ( ) de una cadena. Una matriz de sufijos es básicamente todos los sufijos de la cadena S dispuestos en orden lexicográfico ascendente. Más específicamente, el valor S A [ i ] indica que el sufijo de S a partir de la posición S A [ i ] está clasificado como iSA S SA[i] S SA[i] i en el orden lexicográfico de todos los sufijos de .S
Lo siguiente es la matriz L C P [ i ] indica la longitud del prefijo común más largo entre los sufijos que comienzan desde S A [ i - 1 ] y S A [ i ] . Es decir, realiza un seguimiento de la longitud del prefijo común más largo entre dos sufijos consecutivos de S cuando se disponen en orden lexicográfico.LCP LCP[i] SA[i−1] SA[i] S
Como ejemplo, considere la cadena . Los sufijos en orden lexicográfico serían { a , a b b a b c a , a b c a , b a b c a , b b a b c a , b c a , c a } , entonces S A = [ 7 , 1S=abbabca {a,abbabca,abca,babca,bbabca,bca,ca} para una matriz indexada 1. Lamatriz L C P sería L C P = [ - , 1 , 2 , 0 , 1 , 1 , 0 ] .SA=[7,1,4,3,2,5,6] LCP LCP=[−,1,2,0,1,1,0]
Ahora, dado dos cadenas y B , que les concatenar como S = A # B , donde # es un personaje no está presente tanto en A y B . La razón para elegir dicho carácter es para que al calcular el LCP de dos sufijos, diga a b # d a b d y a bA B S=A#B # A B ab#dabd , la comparación se interrumpa al final de la primera cadena (ya que solo ocurre una vez, dos sufijos diferentes nunca lo tendrán en la misma posición) y no se"desbordarán"en la otra cadena.abd
Ahora, se puede ver que debería poder ver por qué solo necesita ver valores consecutivos en la matriz (el argumento se basa en la contradicción y el hecho de que los sufijos en S A están en orden lexicográfico). Siga revisando la matriz L C P para ver el valor máximo de manera que los dos sufijos que se comparan no pertenezcan a la misma cadena original. Si no pertenecen a la misma cadena original (una comienza en A y la otra en B ), entonces el valor más grande es la longitud de la subcadena común más grande.LCP SA LCP A B
Como ejemplo, considere y B = b c . Entonces, S = a b c a b c # b c . Los sufijos ordenados son { a b c # b c , a b c a b c # b c , b c , b c # b c , b c aA=abcabc B=bc S=abcabc#bc {abc#bc,abcabc#bc,bc,bc#bc,bcabc#bc,c,c#bc,cabc#bc} .
SALCP=[4,1,8,5,2,9,6,3,7]=[−,3,0,2,2,0,1,1,0]
fuente
{#bc,abc#bc,abcabc#bc,bc,bc#bc,bcabc#bc,c,c#bc,cabc#bc}
,SA=[7,4,1,8,5,2,9,6,3]
andLCP=[−,0,3,0,2,2,0,1,1]
The algorithm you found online is not entirely correct. As mentioned by Paresh, it will fail in the example given by him.
However, if you ensure that while checking the LCP, you only check the LCP of substrings of different strings. For example, if you are finding the LCS of strings A and B, then you need to ensure that the adjacent entries of the Suffix Array while checking for LCP are both not from the same string.
More details here.
fuente
I think something like the algorithm you cite should indeed work if a character that is not part of the character set is used as a separator, and the suffix/prefix arrays are built to exclude all strings that contain the separator, probably the intention of the designer. this is basically equivalent to building suffix/prefix arrays for the two separate strings.
it would be helpful for future ref if you posted a link to the algorithm. note that wikipedia has the algorithm for this in pseudocode & many other algorithms. and there are implementations in most standard languages available online.
fuente