# KMP算法

KMP算法

推荐模式串和匹配串下标都从1开始,方便代码编写和理解。

传送门:Acwing 831

next[]数组的含义,next[j]=k

表示已j为结尾的后缀等于以k结尾的前缀,也即是绿颜色的三段是一样的

# KMP算法_第1张图片

匹配过程中,i标记模式字符串扫描到的位置,j+1标记模板字符串待匹配的位置,j从0开始,j+1也就是1,就是第一个参与匹配的位置。

p[j+1]!=s[i]时,表示模板串P的下一个待匹配的位置和模式串的当前扫描到的位置不是同一字符,但是p[1,j]==s[i-j+1,i-1]是匹配的(既然匹配到了j+1的位置,那么j+1之前的位置肯定是匹配成功的)。这个时候就到了上图的情况,要在模板串的前缀中找到一个前缀能匹配以j结尾的后缀,避免绿颜色部分的重复匹配。

#include 
using namespace std;
char p[10005],s[100005];
int n,m;
int nxt[10005];
inline void getNext(){
    for(int i=2,j=0;i<=n;++i){
        //P从2开始计算next数组,next[1]=0,无需计算,j=1的时候,如果j+1不匹配,直接回到起点,故next[1]=0,将j变成0,此时j+1=1为第一个匹配的位置。
        while(j&&p[j+1]!=p[i])j=nxt[j];
        if(p[j+1]==p[i])++j;
        nxt[i]=j;
    }
}
int main(){
    cin>>n>>p+1>>m>>s+1;//使串从下标1开始
    getNext();
    for(int i=1,j=0;i<=m;++i){
        while(j&&p[j+1]!=s[i])j=nxt[j];//其中j是已经匹配成功的位置,j+1才是将要进行匹配的位置
        if(p[j+1]==s[i])++j;//如果匹配成功,更新待匹配的位置
        if(j==n){
            cout<

你可能感兴趣的:(# KMP算法)