Pensando en el aprendizaje de la estructura de datos: algoritmo KMP para resolver la siguiente matriz

1. Análisis de algoritmos

Este es el siguiente algoritmo de matriz resuelto por el algoritmo KMP en la página 110 de la estructura de datos de Wangdaoshu de 2022. El principio no se explica en detalle en el libro, y el pescado salado senior también dijo que este es uno de los algoritmos más oscuros en el todo el curso, que despertó el pensamiento del autor.

void get_next(String T,int next[]){
    int i=1, j=0;
    next[1]=0;
    while(i<T.length){
        if(j==0||ch[i]==T.ch[j]){
            ++i; ++j;
            next[i]=j;  //若pi=pj,则next[j+1]=next[j]+1
        }
        else
            j=next[j];  //否则令j=next[j],循环继续
    }
}

Principio de solución:

1. Primero verifique que la longitud máxima de coincidencia del carácter Y antes del carácter Z a solicitar sea de m caracteres, correspondiente al  T[1]-T[m] inicial , en este momento si  X (T[m+1] ) ==Y , entonces se puede juzgar que  el carácter máximo coincidente antes de  Z es m+1  , por lo que el siguiente es  m+2 ;      

2. Si  X! =Y  , necesita encontrar una cadena ① que coincida con la cadena ②, y dado que hay  n cadenas coincidentes máximas antes  de X,  la cadena ②==cadena ③ y la cadena ①==cadena ③, busque una cadena que coincida con la cadena ① ② cadena , si  ξ==Y en este momento , entonces  next[Z]=n+1 de  Z ;  

Correspondiente al ciclo while en el código anterior

    while(i<T.length){
        if(j==0||ch[i]==T.ch[j]){
            ++i; ++j;
            next[i]=j;  //若pi=pj,则next[j+1]=next[j]+1
        }
        else
            j=next[j]  //否则令j=next[j],循环继续
    }

Dos, plantilla KMP

El i=0 j=-1  en la plantilla  se deben a que la cadena de caracteres en el programa comienza desde el subíndice 0, y Wang Dao explica que el subíndice del primer carácter es 1 de manera predeterminada.

void get_next(string T, int next[]) { 
    memset(next, 0, sizeof(next)); //多组输入时,每次需要初始化next[]数组
    int i = 0, j = -1;
    next[0] = -1;
    while (i < T.length()){
        if (j == -1 || T[i] == T[j]) {
            ++i; ++j;
            next[i] = j;  //若pi=pj,则next[j+1]=next[j]+1
        }
        else
            j = next[j];  //否则令j=next[j],循环继续
    }
}

int Index_KMP(string S, string T, int next[]) //S是字符串,T是模式串
{
	int i = 0, j = 0;
	while (i < S.length() && j < T.length()){
		if (j == -1 || S[i] == T[j]){
			++i; ++j;
		} 
		else
			j = next[j];

		if (j == T.length()) //匹配成功
			return i - T.length();
		else //匹配失败
			return 0;
	}
}

Debe tenerse en cuenta que la función Index_KMP() es una función para obtener el índice coincidente de la cadena de patrones. Si el título requiere el número de subcadenas coincidentes en la cadena, j < T.length() en el bucle while debe ser eliminado , cuyo contenido debe ajustarse de acuerdo con la situación real.

Además, la función get_next() se puede optimizar en la función get_nextval(), que puede acelerar la coincidencia de cadenas. Para obtener detalles del algoritmo, consulte 4.2.3 Optimización adicional del algoritmo KMP en la página P111 de la edición 2022 del libro de texto de Wangdao

void get_nextval(string T, int nextval[]) {
    memset(next, 0, sizeof(next)); //多组输入时,每次需要初始化next[]数组
	int i = 0, j = -1;
	nextval[0] = -1;
	while (i < T.length()) {
		if (j == -1 || T[i] == T[j]) {
			++i; ++j;
			if (T[i] != T[j]) nextval[i] = j;
			else nextval[i] = nextval[j];
		}
		else
			j = nextval[j];
	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_21891843/article/details/123871649
Recomendado
Clasificación