KMP相关

Posted 云深不知处

tags:

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

KMP是一个困扰我很久的算法,听老师或者是学姐讲了差不多有4次了,但是还是搞不太懂,今天终于,终于,终于搞懂了!

                          ——2017-10-29 Vanora

首先推荐一下KMP详解——July

读罢之后内心只有一个感觉:我的KMP终于可以毕业了qwq

学东西千万不要求快!细细地,慢慢地去读这篇文章,相信你也可以从头到尾彻底理解KMP算法呦~

接下来是一些KMP的练手题:

做完这些并且真正搞懂之后,相信你一定就会KMP算法了~(一定要理解了,吃透了!)

1.P3375 【模板】KMP字符串匹配

直通车

思路:

  真正意义上的KMP板子题,很良心

坑点:

  一定要真正理解nxt[]求得到底是什么,是用匹配串求解还是用文本串

上代码:

技术分享
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int M = 1000011;
char s[M],p[M];
int lens,lenp;

int nxt[M];
void getnxt() {
    int k=-1,j=0;
    nxt[0]=-1;
    while(j<lenp) {
        if(k==-1 || p[j]==p[k]) {
            j++;k++;
            nxt[j]=k; //记录更新的nxt值 
        }
        else k=nxt[k];
    }
}

void KMP() {
    int i=0,j=0;
    while(i<lens) {
        if(j==-1 || s[i]==p[j]) i++,j++; 
        //j==-1:没有nxt,所以从一开始进行匹配 
        //s[i]==p[j]:当前文本串与匹配串的位置上的字符匹配成功,继续匹配 
        else j=nxt[j]; //寻找更短的公共前后缀 
        if(j==lenp) {
            printf("%d\n",i-lenp+1);
            i--; //文本串之前已经匹配过了,所以没有再次进行匹配的需要了 
            j=0; //匹配串从新开始进行匹配 
        }
    }
} 

int main() {
    cin>>s>>p;
    lens=strlen(s);
    lenp=strlen(p);
    getnxt();
    KMP();
    for(int i=1; i<=lenp; i++) printf("%d ",nxt[i]);
    return 0;
}
View Code

 

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

POJ-2752(KMP算法+前缀数组的应用)

kmp算法的个人理解

AJAX相关JS代码片段和部分浏览器模型

KMP解决字符串最小循环节相关问题

Jekyll 偏移代码片段高亮的初始行

从零开始配置vim(27)——代码片段