1. 程式人生 > >wenbao與擴展kmp

wenbao與擴展kmp

pri 單獨 name and stdio.h AC main amp ffffff

給定兩個字符串S和T(長度分別為n和m),下標從0開始,定義extend[i]等於S[i]...S[n-1]與T的最長公共前綴的長度,求出所有的extend[i]

next[i]: T[i]...T[m-1]與T的最長公共前綴長度;
extend[i]: S[i]...S[n-1]與T的最長公共前綴的長度。

推薦博客:https://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html

 1 //C/C++ 模板
 2 #include <iostream>
 3 #include <stdio.h>
 4 #include <string
.h> 5 using namespace std; 6 const int N = 101010; 7 int next[N],extand[N]; 8 void getnext(char *T){// next[i]: 以第i位置開始的子串 與 T的公共前綴 9 int i,length = strlen(T); 10 next[0] = length; 11 for(i = 0;i<length-1 && T[i]==T[i+1]; i++); //單獨處理next[1] 12 next[1] = i; 13 int
a = 1; 14 for(int k = 2; k < length; 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<length && T[k+j]==T[j]) j++;// 枚舉(p+1,length) 與(p-k+1,length) 區間比較 19 next[k] = j, a = k;
20 } 21 else next[k] = L; 22 } 23 } 24 void getextand(char *S,char *T){ 25 memset(next,0,sizeof(next)); 26 getnext(T); 27 int Slen = strlen(S), Tlen = strlen(T), a = 0; 28 int MinLen = Slen>Tlen?Tlen:Slen; 29 while(a<MinLen && S[a]==T[a]) a++; 30 extand[0] = a, a = 0; 31 for(int k = 1; k < Slen; k++){ 32 int p = a+extand[a]-1, L = next[k-a]; 33 if( (k-1)+L >= p ){ 34 int j = (p-k+1)>0? (p-k+1) : 0; 35 while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++; 36 extand[k] = j;a = k; 37 } 38 else extand[k] = L; 39 } 40 } 41 42 int main(){ 43 char s[N],t[N]; 44 while(~scanf("%s %s",s,t)){ 45 getextand(s,t); 46 for(int i = 0; i < strlen(t); i++) printf("%d ",next[i]); 47 puts(""); 48 for(int i = 0; i < strlen(s); i++) printf("%d ",extand[i]); 49 puts(""); 50 } 51 } 52 53 /* 54 abababab abab 55 aaaabaaa aaaa 56 */

只有不斷學習才能進步!

wenbao與擴展kmp