Pensando no aprendizado da estrutura de dados: algoritmo KMP para resolver o próximo array

1. Análise de algoritmo

Este é o próximo algoritmo de matriz resolvido pelo algoritmo KMP na página 110 da edição de Wangdaoshu Data Structure de 2022. O princípio não é explicado em detalhes no livro, e Xianyu sênior também disse que este é um dos algoritmos mais obscuros do todo o curso, que despertou o pensamento do 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],循环继续
    }
}

Princípio da solução:

1. Primeiro verifique se o comprimento máximo correspondente do caractere Y antes do caractere Z a ser solicitado é de m caracteres, correspondendo ao inicial  T[1]-T[m] , neste momento se  X (T[m+1] ) ==Y , então pode-se julgar que  o caractere correspondente máximo antes de  Z é m+1  , então o próximo é  m+2 ;      

2. Se  X! =Y  , você precisa encontrar uma string ① que corresponda à string ② e, como há no  máximo n strings correspondentes antes de  X,  string ②==string ③ e string ①==string ③, encontre uma string que corresponda à string ① ② string , se  ξ==Y neste momento , então  next[Z]=n+1 de  Z ;  

Correspondente ao loop while no código acima

    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],循环继续
    }

Dois, modelo KMP

O i=0 j=-1  no modelo  são porque a cadeia de caracteres no programa começa do subscrito 0, e Wang Dao explica que o primeiro caractere subscrito é 1 por padrão.

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;
	}
}

Deve-se observar que a função Index_KMP() é uma função para obter o índice correspondente da string padrão. Se o título exigir o número de substrings correspondentes na string, j < T.length() no loop while precisa ser excluído , cujo conteúdo deve ser ajustado de acordo com a situação real.

Além disso, a função get_next() pode ser otimizada na função get_nextval(), que pode acelerar a correspondência de strings. Para obter detalhes do algoritmo, consulte 4.2.3 Otimização adicional do algoritmo KMP na página P111 do Wangdao 2022 livro didático

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];
	}
}

Acho que você gosta

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