扩展KMP
#include <stdio.h> #include <stdlib.h> #include<map> #include<algorithm> #include<iostream> #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=100010; //字符串长度最大值 int nex[maxn],ex[maxn]; //ex数组即为extend数组 //预处理计算next数组 //void GETNEXT(char *str) //{ // int i=0,j,po,len=strlen(str); // nex[0]=len;//初始化next[0] // while(str[i]==str[i+1]&&i+1<len)//计算next[1] // i++; // nex[1]=i; // po=1;//初始化po的位置 // for(i=2;i<len;i++) // { // if(nex[i-po]+i<nex[po]+po)//第一种情况,可以直接得到next[i]的值 // nex[i]=nex[i-po]; // else//第二种情况,要继续匹配才能得到next[i]的值 // { // j=nex[po]+po-i; // if(j<0)j=0;//如果i>po+next[po],则要从头开始匹配 // while(i+j<len&&str[j]==str[j+i])//计算next[i] // j++; // nex[i]=j; // po=i;//更新po的位置 // } // } //} //计算extend数组 //void EXKMP(char *s1,char *s2) //{ // int i=0,j,po,len=strlen(s1),l2=strlen(s2); // GETNEXT(s2);//计算子串的next数组 // while(s1[i]==s2[i]&&i<l2&&i<len)//计算ex[0] // i++; // ex[0]=i; // po=0;//初始化po的位置 // for(i=1;i<len;i++) // { // if(nex[i-po]+i<ex[po]+po)//第一种情况,直接可以得到ex[i]的值 // ex[i]=nex[i-po]; // else//第二种情况,要继续匹配才能得到ex[i]的值 // { // j=ex[po]+po-i; // if(j<0)j=0;//如果i>ex[po]+po则要从头开始匹配 // while(i+j<len&&j<l2&&s1[j+i]==s2[j])//计算ex[i] // j++; // ex[i]=j; // po=i;//更新po的位置 // } // } //} void GETNEXT(char *s) { int len=strlen(s); int now=0; nex[0]=len; while(now<len&&s[now]==s[now+1])now++; nex[1]=now; int pos=1; for(int i=2;i<len;i++){ if(nex[i-pos]+i<nex[pos]+pos)nex[i]=nex[i-pos]; else{ int j=nex[pos]+pos-i; if(j<0)j=0; while(i+j<len&&s[j]==s[i+j])j++; nex[i]=j; pos=i; } } } void EXKMP(char *s1,char *s2) { GETNEXT(s2); int len1=strlen(s1); int len2=strlen(s2); int now=0; while(now<len1&&now<len2&&s1[now]==s2[now])now++; ex[0]=now; int pos=0; for(int i=1;i<len1;i++){ if(nex[i-pos]+i<ex[pos]+pos)ex[i]=nex[i-pos]; else{ int j=ex[pos]+pos-i; if(j<0)j=0; while(i+j<len1&&j<len2&&s1[i+j]==s2[j])j++; ex[i]=j; pos=i; } } } int main() { char s1[10000],s2[1000]; while(cin>>s1>>s2){ EXKMP(s1,s2); for(int i=0;i<strlen(s2);i++)cout<<nex[i]<<" "; cout<<endl; for(int i=0;i<strlen(s1);i++)cout<<ex[i]<<" "; cout<<endl; } }