KMP 洛谷P3375

题目链接:https://www.luogu.org/problem/P3375

就是一个裸的kmp,还记得很久很久之前,第一次看kmp,看了一天都没看懂,还是浮躁加效率太低了,kmp好好看其实根本就不难

模板码住吧。

KMP时间复杂度是O(n+m)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
typedef long long ll;
#define meminf(a) memset(a,0x3f,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a));
char s1[maxn],s2[maxn];
int nxt[maxn];//用于记录当匹配到模式串的第i位之后失配,该跳转到模式串的哪个位置
int main(){
    scanf("%s%s",s1+1,s2+1);
    //scanf("%s",s2+1);
    int len1=strlen(s1+1),len2=strlen(s2+1);
    //接下来求nxt数组,nxt数组仅由模式串本身决定 
    nxt[0]=0,nxt[1]=0;//第一位,第二位失配了,都只可能以第一位作为新的开头
    int k=0; //k指向的是j指针下一步移动的位置 
    //cout<<233<<endl;
    for(int i=2;i<=len2;i++){
        //这里是从模式串的第二位开始匹配的
        while(s2[i]!=s2[k+1]&&k!=0) k=nxt[k]; 
        if(s2[i]==s2[k+1]) nxt[i]=++k; 
    } 
    
    k=0; 
    for(int i=1;i<=len1;i++){
        while(k&&s1[i]!=s2[k+1]) k=nxt[k];//如果不匹配,则利用nxt数组往回跳
        if(s1[i]==s2[k+1])k++;//如果相等了,则匹配下一位
        if(k==len2)printf("%d
",i-len2+1);
        //如果相等了,我们就输出起始位置
    }
    for(int i=1;i<len2;i++)printf("%d ",nxt[i]);
    printf("%d
",nxt[len2]);
    return 0;
} 
原文地址:https://www.cnblogs.com/qingjiuling/p/11372898.html