扩展KMP,用于求s的后缀的最长前缀。用extand数组表示第i个后缀的最长前缀的字符个数。
注意几点:1.next数组是对T的
2.extand数组是对S的
3.应用:回文,重复串等
代码如下:
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 using namespace std; 5 const int MM=100005; //长度最大值 6 int next[MM],extand[MM]; 7 char S[MM],T[MM]; 8 void GetNext(const char *T){ 9 int len=strlen(T),a=0; 10 next[0]=len; 11 while(a<len-1 && T[a]==T[a+1]) a++; 12 next[1]=a; 13 a=1; 14 for(int k=2;k<len;k++){ 15 int p=a+next[a]-1,L=next[k-a]; 16 if( (k-1)+L >= p){ 17 int j = (p-k+1)>0 ? (p-k+1) : 0; 18 while(k+j<len && T[k+j]==T[j]) j++; 19 next[k]=j; 20 a=k; 21 } 22 else 23 next[k]=L; 24 } 25 } 26 void GetExtand(const char *S,const char *T){ 27 GetNext(T); 28 int slen=strlen(S),tlen=strlen(T),a=0; 29 int MinLen = slen < tlen ? slen : tlen; 30 while(a<MinLen && S[a]==T[a]) a++; 31 extand[0]=a; 32 a=0; 33 for(int k=1;k<slen;k++){ 34 int p=a+extand[a]-1, L=next[k-a]; 35 if( (k-1)+L >= p){ 36 int j= (p-k+1) > 0 ? (p-k+1) : 0; 37 while(k+j<slen && j<tlen && S[k+j]==T[j]) j++; 38 extand[k]=j; 39 a=k; 40 } 41 else 42 extand[k]=L; 43 } 44 } 45 int main(){ 46 while(scanf("%s%s",S,T)==2){ 47 GetExtand(S,T); 48 for(int i=0;i<strlen(T);i++) 49 printf("%d ",next[i]); 50 puts(""); 51 for(int i=0;i<strlen(S);i++) 52 printf("%d ",extand[i]); 53 puts(""); 54 } 55 return 0; 56 }
时间: 2024-11-20 14:14:20