【模板】扩展kmp

来源:互联网 发布:oracle数据导出导入 编辑:程序博客网 时间:2024/06/11 20:20

扩展kmp用于求解模板串S的每一个后缀与串T的LCP,复杂度O(|S|+|T|)
next【i】表示串T【i~(lenT-1)】与串T的LCP(自身匹配)
extend【i】表示S【i~(lenS-1)】与串T的LCP
通过维护一个p=i+next【i】-1的最大值,对于超过p的部分暴力比较求解即可
PPT:https://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html
Blog:http://www.cnblogs.com/10jschen/archive/2012/09/03/2668149.html
板子出处:http://www.cnblogs.com/10jschen/archive/2012/09/03/2668149.html

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=1000010;int nxt[N],ex[N];char a[N],b[N];void Get_nxt(char *s,int len){    nxt[0]=len;    int a=0;    while(a<len-1&&s[a]==s[a+1]) a++;    nxt[1]=a;    a=1;    for(int k=2;k<len;k++)    {        int p=a+nxt[a]-1,L=nxt[k-a];        if(k+L-1>=p)        {            int j=max(p-k+1,0);            while(k+j<len&&s[k+j]==s[j]) j++;            nxt[a=k]=j;        }        else nxt[k]=L;    }}void Get_extend(char *S,int lens,char *T,int lent){    int a=0,len=min(lens,lent);    while(a<len&&S[a]==T[a]) a++;    ex[0]=a;    a=0;    for(int k=1;k<lens;k++)    {        int p=a+ex[a]-1,L=nxt[k-a];        if(k+L-1>=p)        {            int j=max(p-k+1,0);            while(k+j<lens&&j<lent&&S[k+j]==T[j]) j++;            ex[a=k]=j;        }        else ex[k]=L;    }}int main(){    while(~scanf("%s %s",a,b))    {        int lena=strlen(a),lenb=strlen(b);        Get_nxt(b,lenb);        Get_extend(a,lena,b,lenb);        for(int i=0;i<lenb;i++) printf("%d ",nxt[i]);        printf("\n");        for(int i=0;i<lena;i++) printf("%d ",ex[i]);        printf("\n");    }    return 0;}
原创粉丝点击