Explicación detallada del algoritmo KMP (comprensión personal)

Explicación detallada del algoritmo KMP

Sabemos que el algoritmo BF es un método de fuerza bruta, que requiere tiempo y esfuerzo, entonces, ¿qué debemos hacer? Los tres grandes dioses de DEKnuth, J, H, Morris y VRPratt crearon un algoritmo de emparejamiento rápido para nosotros: el algoritmo KMP. El núcleo de este algoritmo es que reduce el proceso de retroceso del puntero de cadena principal y mejora enormemente nuestro emparejamiento. velocidad.
El retroceso del puntero de cadena principal mencionado anteriormente, ¿qué es esto? Déjame contarte sobre los pasos de implementación de KMP.

1. Pasos

  • La obtención del siguiente valor de la cadena principal
    se debe a que KMP ha calculado el siguiente valor de la cadena principal antes de hacer coincidir, por lo que se reduce el retroceso del puntero de BF. Para darte una analogía:
主串:ababbbab
子串:abb

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

El siguiente código es para el siguiente [] de la cadena 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];
    }
}

El propósito de ir a continuación es averiguar si la subcadena frente al carácter que no coincide tiene el mismo prefijo y sufijo. Si lo hay, omítalo directamente. Aquí hay una pequeña elusión. Te presentaré captura de pantalla en un momento. Por tanto, el algoritmo KMP evita el problema del retroceso del puntero.
Para hacerlo más simple, el algoritmo de retroceso también se conoce como "heurística". Al resolver el problema, cada paso que da es una actitud de intento. Si encuentra que la elección actual no es la mejor, o si continúa así, definitivamente no logrará su objetivo, debe regresar inmediatamente y elegir otra vez. Este método de retroceder y luego retroceder cuando falla es el algoritmo de retroceso.

Haz pareja

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

No digas tonterías, solo ve a la imagen. Muestre a todos el proceso del código anterior
Inserte la descripción de la imagen aquí

Proceso específico:
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Puedes ver las tres imágenes de arriba. Las primeras cinco están emparejadas, pero cuando la sexta no coincide, ¿qué debo hacer? i = next[i]Esta sintaxis se usa para hacer que la subcadena apunte a B en la cuarta imagen y luego comenzar a emparejar desde 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;
}

Supongo que te gusta

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