algoritmo detallada KMP es simple y fácil de entender

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;
Aquí Insertar imagen Descripción
y el prefijo al sufijo AB AB posición movió;
Aquí Insertar imagen Descripción
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;
Aquí Insertar imagen Descripción
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.
Aquí Insertar imagen Descripción

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;
Aquí Insertar imagen Descripción
posición y el prefijo de la ABA sufijo ABA movido;
Aquí Insertar imagen Descripción
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;
Aquí Insertar imagen Descripción
y el prefijo movido a la posición a del sufijo a, continúa a la altura, el partido tiene éxito.
Aquí Insertar imagen Descripción

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:
Aquí Insertar imagen Descripción
! 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;
}
Publicado 47 artículos originales · ganado elogios 238 · Vistas 6381

Supongo que te gusta

Origin blog.csdn.net/weixin_43912621/article/details/105173930
Recomendado
Clasificación