求前缀和后缀的最长匹配长度,题目要求有点多,要求如何合并长度不等的话以长度短的优先,相等以字典序优先。
注意是前缀和后缀,后缀必须到结尾,前缀必须从开头开始。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int p[100005];
char s1[100005];
char s2[100005];
int n,m;
void getnext(char * s,int m)
{
p[0]=p[1]=0;
for (int i=2;i<=m;i++)
{
int j=p[i-1];
while (j>0&&s[j+1]!=s[i])
j=p[j];
if (s1[j+1]==s1[i])
j++;
p[i]=j;
}
}
int KMP(char *a,char *b,int lena,int lenb)
{
int j=1;
for (int i=1;i<=lena;i++,j++)
{
//cout<<i<<" "<<j<<endl;
if (a[i]==b[j]&&j==lenb&&i!=lena)
{
j=p[j];
continue ;
}
if (a[i]==b[j])
{
continue;
}
j--;
while (j>0&&a[i]!=b[j+1])
j=p[j];
if (a[i]==b[j+1])
j++;
}
return j-1;
}
int main()
{
while (scanf("%s%s",s1+1,s2+1)!=EOF)
{
n=strlen(s1+1);
m=strlen(s2+1);
getnext(s1,n);
int len1=KMP(s2,s1,m,n);
//cout<<endl;
getnext(s2,m);
int len2=KMP(s1,s2,n,m);
//cout<<endl;
//cout<<len1<<" "<<len2<<endl;
if (len1<len2)
{
printf("%s%s\n",s1+1,s2+len2+1);
}
else if(len1>len2)
{
printf("%s%s\n",s2+1,s1+len1+1);
}
else
{
int i=1;
while (s1[i]==s2[i])
i++;
if (s1[i]<s2[i])
printf("%s%s\n",s1+1,s2+len2+1);
else
printf("%s%s\n",s2+1,s1+len1+1);
}
}
}