KMP

来源:互联网 发布:网络光纤收发器 编辑:程序博客网 时间:2024/05/17 19:14
%:pragma GCC optimize(2)#include<bits/stdc++.h>using namespace std;char st[10000001];char zi[10000001];int next[10000001];int main(){    scanf("%s%s",st,zi);    int k=0;int len=strlen(zi);    for(int i=1;i<len;i++)    {        while(k>0&&zi[k]!=zi[i])        {            k=next[k-1];        }        if(zi[k]==zi[i]) k++;        next[i]=k;    }    k=0;int ll=strlen(st);    for(int i=0;i<=ll;i++)    {        while(k>0&&zi[k]!=st[i])k=next[k-1];      //相当于主串不动,子串动。        if(zi[k]==st[i]) k++;        if(k==len){printf("%d\n",i-len+2);break;}    }}
/*总结一下,KMP的算法分为两部分,计算ne数组和进行匹配。每次匹配的本质都是根据主串到某一位置的后缀和模式串前缀匹配时1.他们的后一位都相同,那么多一位2.他们的后一位不同,我们可以利用预处理的数据,调用包含在该后缀的前缀和该前缀的后缀(一定在模式串中,所以可以预处理)的下一个这样相同的子串,比较下一位,若相同则为最大匹配长度3.若递归到0则直接判相不相同取决长度,实际上这和前面必定加一的部分写在了一起。( if(t[wei]==s[i]) wei++;其实如果wei不是0就直接加1)4.如果达到匹配,输出结果。 */#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;int ne[1000001];char s[1000001];char t[1000001];int main(){    scanf("%s%s",s,t);    int lent=strlen(t),lens=strlen(s);    int wei=0;    for(int i=1;i<lent;i++)    {        while(wei&&t[wei]!=t[i]) wei=ne[wei-1];        if(t[wei]==t[i]) wei++;        ne[i]=wei;    }    wei=0;    for(int i=0;i<lens;i++)    {        while(wei&&t[wei]!=s[i]) wei=ne[wei-1];        if(t[wei]==s[i]) wei++;        if(wei==lent)        {            printf("%d",i-lent+2);            return 0;        }    }}