题目分析:给连个字符串s1, s2,字符串长度不超过50000,最长的字符串s3,s3即是s1的前缀,又是s2的后缀
思路:把s1和s2拼接起来成s,然后用KMP的next数组,求出从开头都每一个字符的既是真前缀和真后缀的字符串的长度。
注意:1.为了应对abcba bcba和.aaa aaaa这种数据,只有在两个字符串之间见一个字符#,
2.答案就是s的最后一个字符的下一个位置对应的next-1
测试数据:
abc abcd
hellolleh hello
hello ello
ello hello
hellolleh olleh
clinton homer
aaaaa aaaaaa
clinton homer
riemann marjorie
abcba bcba
代码:
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
int next[100010];
char s1[101000],s2[51000],s[101000];
int len1,len2,len;
void GetNext()
{
next[1]=0;
int j=1,k=0;
while(j<=len+1)//len模式串的长度
{
if((k==0)||(s[j]==s[k]))
{
j++;
k++;
next[j]=k;
}
else
{
k=next[k];
}
}
}
int main()
{
while(scanf("%s",s1)!=EOF)
{
bool flag=true;
int i;
scanf("%s",s2);
len1=strlen(s1);
len2=strlen(s2);
len=len1+len2+1;
strcpy(s+1,s1);
s[len1+1]='#';
for(i=0;i<len2;i++)
{
s[len1+2+i]=s2[i];
}
s[len+2]='\0';
for(i=2;i<=len;i++)
{
if(s[i]!='#'&&s[i]!=s[1])
{
flag=false;
break;
}
}
if(flag==true)
{
int x=(len1>len2)?len2:len1;
for(i=1;i<=x;i++)
printf("%c",s[i]);
printf(" %d\n",x);
continue;
}
GetNext();
int ans=next[len+1]-1;
if(ans==0)
printf("0\n");
else
{
for(i=0;i<ans;i++)
printf("%c",s1[i]);
printf(" %d\n",ans);
}
}
return 0;
}