Explicação detalhada do algoritmo KMP (compreensão pessoal)

Explicação detalhada do algoritmo KMP

Sabemos que o algoritmo BF é um método de força bruta, que exige tempo e esforço, então o que devemos fazer? Os três grandes deuses de DEKnuth, J, H, Morris e VRPratt criaram um algoritmo de correspondência rápida para nós - o algoritmo KMP. O núcleo desse algoritmo é que ele reduz o processo de retrocesso do ponteiro da string principal e melhora muito nossa correspondência. Rapidez.
O retrocesso do ponteiro da string principal mencionado acima, o que é isso? Deixe-me falar sobre as etapas de implementação do KMP.

1. Passos

  • A obtenção do próximo valor da string principal
    ocorre porque o KMP calculou o próximo valor da string principal antes da correspondência, de modo que o retrocesso do ponteiro de BF é reduzido. Para dar uma analogia:
主串:ababbbab
子串:abb

第一轮匹配:匹配到了第一个字符
ababbbab
a
第二轮匹配:匹配到了第二个字符
ababbbab
ab
第三轮匹配:匹配失败
匹配失败之后BF算法是这样的,从主串第二个字符又开始匹配,这就较做主串指针回溯。
ababbbab
 abb

O código a seguir é para o próximo [] da string principal

void getnext() {
    
    
    next[0] = -1;
    int i = 0, j = -1;
    int len = strlen(T);
    while(i < len) {
    
    
        if(j == -1 || T[i] == T[j])
            next[++i] = ++j;
         else
            j = next[j];
    }
}

O objetivo do próximo passo é descobrir se a substring na frente do caractere que não corresponde tem o mesmo prefixo e sufixo. Se houver, pule-o diretamente. Aqui está uma pequena evasão. Apresentarei um captura de tela em um momento. Portanto, o algoritmo KMP evita o problema de retrocesso do ponteiro.
Para simplificar, o algoritmo de backtracking também é conhecido como "heurística". Ao resolver o problema, cada passo que você dá é uma atitude de tentativa. Se você achar que a escolha atual não é a melhor, ou se continuar assim, definitivamente não alcançará seu objetivo, você deve imediatamente voltar e escolher novamente. Este método de voltar e voltar quando falha é o algoritmo de retrocesso.

Fazer uma combinação

bool KMP() {
    
    
    getnext();
    int len1 = strlen(T);
    int len2 = strlen(S);
    int i = 0, j = 0;     //i指向模式串T,j指向主串S
    while(j < len2) {
    
    
        if(T[i] == S[j]) {
    
     
            i++;
            j++;
            if(i == len2) {
    
    
                return true;
            }
        } else {
    
    
            i = next[i];
            if(i == -1) {
    
    
                j++;i++;
            }
        }
    }
    return false;
}

Não fale bobagem, apenas vá para a foto. Mostre a todos o processo do código acima
Insira a descrição da imagem aqui

Processo específico:
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
Você pode ver as três fotos acima. As cinco primeiras são correspondidas, mas quando a sexta não é correspondida, o que devo fazer? i = next[i]Essa sintaxe é usada para fazer a substring apontar para B na quarta imagem e, em seguida, iniciar o emparelhamento a partir de B.

  • Código
#include <iostream>
#include<cstring>
#include <string>
typedef long long ll;
using namespace std;


bool KMP(char *T,char*S) {
    
    

    int next[100];
    next[0] = -1;
    int i = 0, j = -1;
    int len = strlen(T);
    while(i < len) {
    
    
        if(j == -1 || T[i] == T[j])
        {
    
    
          i++;
          j++;
          next[i] = j;
        }

         else
         {
    
    
             j = next[j];
         }

    }
    int len1 = strlen(T);
    int len2 = strlen(S);
    int i_ = 0, j_ = 0;     //i指向模式串T,j指向主串S

    while(j_ < len2) {
    
    
        if(T[i_] == S[j_]) {
    
    

            i_++;
            j_++;
            if(i_ == len2) {
    
    

                return true;
            }
        } else {
    
    

            i_ = next[i_];
            if(i_ == -1) {
    
    
                j_++;i_++;
            }
        }
    }
    return false;
}

int main()
{
    
    
	char a[] = "ABBABBABAB";
	char b[] = "ABBAB";
	bool m = KMP(a,b);
	printf("%d\n",m);
	return 0;
}

Acho que você gosta

Origin blog.csdn.net/qq_45125250/article/details/109684508
Recomendado
Clasificación