HDU 2594 Simpsons’ Hidden Talents(KMP求s1前缀和s2后缀相同部分)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2594

题目大意:给两串字符串s1,s2,,找到最长子串满足既是s1的前缀又是s2的后缀,输出子串,及相应长度。

解题思路:这题是不是跟POJ 2752很像,没错,我们只要将s1、s2合并,不断递归直到找到长度小于等于s1、s2的公共前后缀即可。

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=1e6+5;
 8 
 9 int nxt[N];
10 char s1[N],s2[N];
11 
12 void getnext(char *p,int m){
13     int i,j;
14     i=0,j=nxt[0]=-1;
15     while(i<m){
16         while(j!=-1&&p[i]!=p[j])
17             j=nxt[j];
18         nxt[++i]=++j;
19     }
20 }
21 
22 int main(){
23     while(~scanf("%s",s1)){
24         scanf("%s",s2);
25         int m=strlen(s1),n=strlen(s2);
26         int cnt=m;
27         //合并s1,s2求nxt数组
28         for(int i=0;i<n;i++){
29             s1[cnt++]=s2[i];
30         }
31         s1[cnt]='\0';
32         getnext(s1,cnt);
33         int ans=nxt[cnt];
34         //s1、s2合并后公共前后缀长度可能大于s1或s2原来的长度,所以要回溯一下找到长度刚好小于s1、s2的公共前后缀
35         while(ans!=-1){
36             if(ans<=m&&ans<=n)
37                 break;
38             ans=nxt[ans];
39         }
40         if(ans>0){
41             for(int i=0;i<ans;i++){
42                 printf("%c",s1[i]);
43             }
44             printf(" %d\n",ans);
45         }
46         else
47             printf("%d\n",ans);
48     }
49     return 0;
50 }

 

posted @ 2018-03-02 00:02  Yeader  阅读(228)  评论(0编辑  收藏  举报