Acerca de KMP algoritmo
KMP algoritmo es un algoritmo de coincidencia de cadenas mejorado, propuesto por DEKnuth, JHMorris y VRPratt, por lo que la gente llama Knuth - Morris - Pratt operación (denominado algoritmo KMP). El núcleo KMP algoritmo utilizando la información no coincide, para reducir al mínimo el número de match principal cadena de patrón de encordado para lograr el propósito del juego rápidamente. aplicación específico se ejecuta mediante una función next (), función de adaptación local de sí mismo contiene información de cadena de patrón. KMP tiempo complejidad del algoritmo O (m + n).
En términos simples:
KMP algoritmo, utilizando la misma cadena de patrón es el más largo prefijo y un sufijo para moverse, y no requiere de la parte posterior principal cadena, a fin de lograr partido rápido.
Por ejemplo:
A continuación, cuando un desajuste se produce en las flechas, para encontrar el más largo prefijo y sufijo de la misma antes de una flecha patrón de cadena subcadena es AB;
y el prefijo al sufijo AB AB posición movió;
continuará igualando la misma razón, no se produce coincida con la cadena patrón que se encuentra antes de la flecha más larga subcadena mismo prefijo y sufijo para una;
y el prefijo movido a la posición de una de los sufijos a, ya que está más allá de la longitud de la cadena principal partido de falla.
Otro ejemplo:
A continuación, cuando un desajuste se produce en las flechas, para encontrar el más largo prefijo y sufijo de la misma antes de que una cadena de patrón flecha subcadena de ABA;
posición y el prefijo de la ABA sufijo ABA movido;
continuará igualando la misma razón, no se produce coincida cadena patrón que se encuentra antes de la flecha más larga subcadena mismo prefijo y sufijo para a;
y el prefijo movido a la posición a del sufijo a, continúa a la altura, el partido tiene éxito.
Obtenido siguiente matriz
el modo de conjunto de cuerdas es p, cadena de patrón es de notar que el índice es de 0 a P.SIZE () - 1, y la siguiente matriz correspondiente a la misma es de 1 a P.SIZE (), junto [0] = - 1.
void getNext(string p, int *next)
{
next[0]=-1;
int i=0,j=-1;//j是前缀,y是后缀
while (i<p.size())
{
if(j==-1||p[i]==p[j])
{
++i;
++j;
next[i]=j;
}
else
{
j=next[j];//回溯
}
}
}
El más difícil de entender es la frase,
j=next[j];//回溯
¿Por qué es esto así? Pero espera, por ejemplo:
! Cuando i = 5, j = 3, es decir, la posición de la flecha negro, p [i] = p [ j], i , y j índices de 0 a P.SIZE (), entonces j = siguiente [j], es decir, j = 1, es decir, la posición de la flecha desigual rojo continúa de nuevo a j = 0, por lo que el ahorro de tiempo atrás. El prefijo posterior fechas originales se sabe, nuestro siguiente almacenado en la matriz es igual a la más larga prefijo y un sufijo para cada índice.
Implementación en C ++:
#include<iostream>
using namespace std;
void getNext(string p, int *next)
{
next[0]=-1;
int i=0,j=-1;
while (i<p.size())
{
if(j==-1||p[i]==p[j])
{
++i;
++j;
next[i]=j;
}
else
{
j=next[j];
}
}
for(int i=0;i<=p.size();i++)
{
cout<<next[i]<<" ";
}
}
int kmp(string x,string y,int *next)
{
int i=0,j=0;
while(true)
{
if(x[i]==y[j]||j==-1)
{
i++;j++;
}
else
{
j=next[j];
}
if(i==x.size()||j==y.size()) break;
}
if(j==y.size())
{
return i-j;
}
else return -1;
}
int main()
{
string x;string y;
int *next=new int[1000005];
cin>>x>>y;
getNext(y,next);
int ans=kmp(x,y,next);
cout<<ans;
return 0;
}