首页 > 代码库 > KMP算法

KMP算法

这个算法太狗血,弄了好几天才明白一点,而且网上不同的博客写的方法不相同,表示很无奈啊。。。

接下来我要讲一讲我理解的KMP,我理解的有点浅,主要给几个事例,就不模拟计算过程了,具体KMP是什么,或者想要知道大致模拟过程的,自行百度。

先粘上代码

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int next[10000];
void prekmp(char x[], int m) {//这一步坑爹,next数组为一张部分匹配表
    int i = 0, j = -1;
     next[0] = -1;
     while(i < m) {
         while(j != -1  && x[i] != x[j] ) j = next[j];
         if(x[++i] == x[++j]) next[i] = next[j];
         else next[i] = j;
     }
}
int KMP(char x[], int m, char y[], int n) {这个还好理解
    int i = 0, j = 0;
    int ans = 0;
    prekmp(x, m);
    while(i < n) {
        while(j != -1 && x[j] != y[i]) j = next[j];//用到next数组,不用一个一个对比,直接用放在next的位置,位置文章最后有解释
         i++; j++;
        if(j >= m) {
            ans++;
            j = next[j];
        }
    }
    return ans;
}
int main() {
    //freopen("in.txt","r",stdin);
    //freopen("out.txt,"w",stdout");
    ios_base::sync_with_stdio(0);cin.tie();
     char x[10000], y[10000];
     scanf("%s%s",y,x);
     int m = strlen(x); 
     int n = strlen(y);
     cout << endl;
     cout << KMP(x, m, y, n) << endl;
     for(int i = 0; i < m; i++)//print value
         cout << next[i] << "" ;
     cout << endl;
     return 0;
}

 

 

 

next数组的事例

位置都是从0开始

abc            -1 0 0

abca          -1 0 0 -1  如果字母跟首字母相同,就为-1

abcabe        -1 0 0 -1 0 2  e字母和c字母不相同,所以e字母指向c的位置

abcdabead       -1 0 0 0 -1 0 2 -1 1  第三个a同第三个a之前字符串的比较,最后一个字母d指向第二个字母b的位置

abcabcabde        -1 0 0 -1 0 0 -1 0 5 0  第三个a之前有连续重复的,第三个指向第6个字母的位置  

abcabdabea        -1 0 0 -1 0 2 -1 0 2 -1  第三个a之前的不连续,所以指向第三个字母的位置

KMP算法