扩展kmp模板

来源:互联网 发布:电脑windows壁纸 编辑:程序博客网 时间:2024/05/22 12:17
#include <iostream>#include <cstring>using namespace std;const int N = 101010;int Next[N],extand[N];void getNext(char *T){// Next[i]: 以第i位置开始的子串 与 T的公共前缀    int i,length = (int)strlen(T);    Next[0] = length;    for(i = 0;i<length-1 && T[i]==T[i+1]; i++);    Next[1] = i;    int a = 1;    for(int k = 2; k < length; k++){        int p = a+Next[a]-1, L = Next[k-a];        if( (k-1)+L >= p ){            int j = (p-k+1)>0? (p-k+1) : 0;            while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较            Next[k] = j, a = k;        }        else Next[k] = L;    }}void getextand(char *S,char *T){    memset(Next,0,sizeof(Next));    getNext(T);    int Slen = (int)strlen(S), Tlen = (int) strlen(T), a = 0;    int MinLen = Slen>Tlen?Tlen:Slen;    while(a<MinLen && S[a]==T[a])        a++;    extand[0] = a, a = 0;    for(int k = 1; k < Slen; k++){        int p = a+extand[a]-1, L = Next[k-a];        if( (k-1)+L >= p ){            int j = (p-k+1)>0? (p-k+1) : 0;            while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++;            extand[k] = j;a = k;        }        else extand[k] = L;    }}int main(){    char s[N],t[N];    while(~scanf("%s %s",s,t)){        getextand(s,t);        for(int i = 0; i < strlen(t); i++)            printf("i=%d next[i]=%d\n",i,Next[i]);        puts("");        for(int i = 0; i < strlen(s); i++)            printf("i=%d extend[i]=%d\n",i,extand[i]);        puts("");    }}

原创粉丝点击