kmp算法的理解

Posted kstranger

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kmp算法的理解相关的知识,希望对你有一定的参考价值。

我发现想出kmp算法的人tql,我理解都要理解半天(太抽象了QAQ)。

kmp代码的自己理解:

#include <string>
#include <iostream>
#include <vector>
using namespace std;
const int N = 10000;

int ne[N];

void getne(string p){
    int len=0;
    //len表示最长公共前后缀的长度
    ne[0]=0;
    //第一个字母的ne初始化为0由于以后会向右移动一位那么当前所表示的位置其实是后一位匹配错的时候应该回溯的位置
    for(int i=1;i<p.size();i++){
        while(len>0&&p[len]!=p[i])len=ne[len-1];
        //由于这里的len每次指的是前一个位置的最大前缀的后面一位的位置,所以就要匹配当前位置和i的字母是否匹配,如果不匹配那么就应该找前缀的最长公共前缀(相当于是递归搜索)
        //如果len等于了i那么就把len++
        if(p[len]==p[i])len++;
        ne[i]=len;
    }
    //这里是把ne数组向后移一位目的是为了以后处理匹配的时候方便
    for(int i=p.size();i>0;i--){
        ne[i]=ne[i-1];
    }
    ne[0]=-1;
}


vector<int> kmp(string base,string s){
    getne(s);
    vector<int> res;
    int i=0,j=0;
    while(i<base.size()){
        if(base[i]==s[j]){
            if(j==s.size()-1){
                //如果匹配到了那么就把开头的位置添加进来
                res.push_back(i-j);
                j=ne[j];
            }
            else {
                //如果当前位置一样就匹配下一位
                i++;
                j++;
            }
        }
        else {
            if(ne[j]==-1){
                //如果第一位都不一样,那么就i和j都向后移(意思是整个字符串向后移)
                i++;
                j++;
            }
            else {
                //如果中间某个位置不匹配,那么就移到它的ne的位置继续匹配,由于前后缀相同所以ne前的位置上的字符一定是符合的
                j=ne[j];
            }
        }
    }
    
    return res;
}
int main(){
    int n,m;
    cin>>n;
    string s1;
    cin>>s1;
    cin>>m;
    string s2;
    cin>>s2;
    auto res=kmp(s2,s1);
    for(int i=0;i<res.size();i++){
        cout<<res[i]<<" ";
    }
}

 

以上是关于kmp算法的理解的主要内容,如果未能解决你的问题,请参考以下文章

KMP算法的理解和代码实现

kmp算法的理解

kmp算法详解

对KMP算法小理解

KMP算法详细解释,带你理解k=next[k](逐代码分析)

KMP算法详细解释,带你理解k=next[k](逐代码分析)