Se pueden utilizar matrices de sufijos para este problema. Contienen las posiciones iniciales de cada sufijo de la cadena ordenada en orden lexicográfico. Aunque pueden construirse ingenuamente en complejidad , existen métodos para construirlos en complejidad Θ ( n ) . Ver por ejemplo esto y esto . Llamemos a este sufijo array SA.O ( n logn )Θ ( n )
Una vez que se ha construido la matriz de sufijos, necesitamos construir una matriz de prefijo común más largo (LCP) para la matriz de sufijos. La matriz LCP almacena la longitud del prefijo común más largo entre dos prefijos consecutivos en la matriz de sufijos (sufijos lexicográficos consecutivos). Por lo tanto, LCP [i] contiene la longitud del prefijo común más largo entre SA [i] y SA [i + 1]. Esta matriz también se puede construir en tiempo lineal: vea aquí , aquí y aquí para algunas buenas referencias.
Ahora, para calcular la longitud del prefijo más largo común a cualquiera de los dos sufijos en el árbol de sufijos (en lugar de sufijos consecutivos), necesitamos usar alguna estructura de datos RMQ . Se ha mostrado en las referencias anteriores (y se puede ver fácilmente si la matriz se visualiza como un árbol de sufijos), que la longitud del prefijo común más largo entre dos sufijos que tienen posiciones y v ( u < v ) en la matriz de sufijos , se puede obtener como m i n u < = k < = v - 1 L C P [ k ]tuvu < vm i nu < = k < = v - 1L CPAGS[ k ]. Un buen RMQ puede preprocesar la matriz en el tiempo O ( n ) u O ( n log n ) y responder a las consultas de la forma L C P [ u , v ] en el tiempo O ( 1 ) . Vea aquí un breve algoritmo RMQ, y aquí un buen tutorial sobre RMQ y la relación (y reducciones) entre LCA y RMQ. Esto tiene otro buen enfoque alternativo.L CPAGSO ( n )O ( n logn )L CPAGS[ u , v ]O ( 1 )
Con esta información, construimos la matriz de sufijos y las matrices asociadas (como se describió anteriormente) para la concatenación de las dos cadenas con un delimitador en el medio (como T # P, donde '#' no aparece en ninguna de las cadenas). Entonces, podemos realizar k coincidencia de cadenas de desajuste utilizando el método "canguro". Esto y esto explican el método canguro en el contexto de los árboles de sufijos, pero también se pueden aplicar directamente a las matrices de sufijos. Para cada índice del texto T , encuentre el L C P del sufijo de T que comienza en i y el sufijo de PyoTL CPAGSTyoPAGScomenzando en 0. Esto proporciona la ubicación después de la cual se produce la primera falta de coincidencia al hacer coincidir con T [ i ] . Deje que esta longitud sea l 0 . Omita el carácter no coincidente en T y P e intente hacer coincidir las cadenas restantes. Es decir, nuevamente encuentre el L C P de T [ i + l 0 + 1 ] y P [ l 0 + 1 ] . Repita esto hasta obtener k discrepancias, o cualquiera de las cadenas termina. CadaPAGST[ i ]l0 0TPAGSL CPAGST[ i + l0 0+ 1 ]PAGS[ l0 0+ 1 ]k es O ( 1 ) . Hay O ( k ) L C P 's para cada índice i de T , lo que da una complejidad total de O ( n k ) .L CPAGSO ( 1 )O ( k ) L CPAGSyoTO ( n k )
Utilicé un RMQ más fácil de implementar que daba una complejidad total de u O ( n k + n log nO ( n k + ( n + m ) log( n + m ) ) si m = O ( n ) , pero también se puede hacer en O ( n k ) como se describió anteriormente. Puede haber otros métodos directos para este problema, pero este es un enfoque poderoso y genérico que se puede aplicar a muchos problemas similares.O ( n k + n logn )m = O ( n )O ( n k )