Simpsons’ Hidden Talents HDU - 2594
KMP+字符串的运用
一开始计算错了时间复杂度,还以为可以直接暴力....
错解思路:
求公共最长的前缀和后缀,如果直接将字符串拼接在一起,如果遇到这样的测试样例eg:s1 = aaa,s2 = aaa就会输出错误,所以我们必须分隔开s1和s2
正解思路:
我们不能让s2认为属于s1部分的也是它自己的,所以我们可以在拼接s1和s2的时候插入一个空格,这样就可以分隔开s1和s2
易错点:
如果我们从后缀开始求匹配的字符串就会遇到如下错误
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 50010;//暴力会TLE,不要计算错时间复杂度 4 string s1,s2; 5 char a[N*2]; 6 int ne[N*2]; 7 int main() 8 { 9 while(cin>>s1) 10 { 11 int idx = 0; bool flag = true; 12 cin>>s2; 13 string prime = s1+" "+s2; 14 int alen = s1.size(); int blen = s2.size(); 15 while(idx<prime.size()){ 16 a[idx+1] = prime[idx]; 17 idx++; 18 } 19 a[idx+1] = '\0'; 20 int clen = strlen(a+1); 21 for(int i=2,j=0;i<=clen;i++){ 22 while(j&&a[i]!=a[j+1]) j = ne[j]; 23 if(a[i]==a[j+1]) j++; 24 ne[i] = j; 25 } 26 if(ne[clen]<=alen){ 27 int st = clen-ne[clen]+1; 28 if(ne[st]==1){ 29 flag = false; 30 for(int i=st;i<=clen;i++) printf("%c",a[i]); 31 printf(" %d\n",ne[clen]); 32 } 33 } 34 if(flag) printf("0\n"); 35 } 36 return 0; 37 }
我们不需要判断匹配的字符串起始是否匹配,因为如果最后一个字符ne[i]!=0,那么前面肯定匹配
以下是修正代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 50010;//暴力会TLE,不要计算错时间复杂度 4 string s1,s2; 5 char a[N*2]; 6 int ne[N*2]; 7 int main() 8 { 9 while(cin>>s1) 10 { 11 int idx = 0; bool flag = true; 12 cin>>s2; 13 string prime = s1+" "+s2; 14 int alen = s1.size(); int blen = s2.size(); 15 while(idx<prime.size()){ 16 a[idx+1] = prime[idx]; 17 idx++; 18 } 19 a[idx+1] = '\0'; 20 int clen = strlen(a+1); 21 for(int i=2,j=0;i<=clen;i++){ 22 while(j&&a[i]!=a[j+1]) j = ne[j]; 23 if(a[i]==a[j+1]) j++; 24 ne[i] = j; 25 } 26 if(ne[clen]<=alen&&ne[clen]){ 27 for(int i=1;i<=ne[clen];i++) printf("%c",a[i]); 28 printf(" %d\n",ne[clen]); 29 flag = false; 30 } 31 if(flag) printf("0\n"); 32 } 33 return 0; 34 }