#include <stdio.h>
#include <string.h>
int next[100005];
void build_next(char str[])
{
int i=0,j=-1;
next[0] = -1;
int len2=strlen(str);
while (i < len2)
{
if (j==-1 || str[i] == str[j])
{
i++;
j++;
if (str[i] != str[j])
{
next[i] = j;
}
else
next[i] = next[j];
}
else
j = next[j];
}
}
int KMP(char str1[],char str2[])
{
int len1=strlen(str1);
int len2=strlen(str2);
build_next(str2);
int i=0,j=0,cnt=0;
while (i < len1 &&j <len2)
{
if (j==-1 || str1[i] == str2[j])
{
i++;
j++;
}
else
j = next[j];
}
if(i==len1)
return j;
return 0;
}
int main()
{
int N,n,i,m;
char str1[100005],str2[100005];
while (~scanf("%s%s",str1,str2))
{
// gets(str2); //gets在这里不行,有空格
n=KMP(str1,str2);
m=KMP(str2,str1); //还要考虑模式串的问题,两个字符串都可以作为模式串,所以要有两个KMP函数
if(m == n)
{
if(strcmp(str1,str2)>0)
{
printf("%s",str2);
printf("%s\n",str1+n);
}
else
{
printf("%s",str1);
printf("%s\n",str2+n);
}
}
else if(n>m)
{
printf("%s",str1);
printf("%s\n",str2+n);
}
else
{
printf("%s",str2);
printf("%s\n",str1+m);
}
}
return 0;
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
分析:主要是看清题目的意思。
asdf 和 sdfg asdf的后缀和sdfg的前缀有相同的sdf 所以在相加之后等于: asdfg
asdf ghjk 之间没有共同的前后缀,所以加起来等于 asdfghjk
还要考虑模式串的问题,两个字符串都可以作为模式串,所以要有两个KMP函数
题目最后说guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.
输出的时候还要满足前面的字符串的字典序要小于后面的字典序
比如 asdfa 和 asdf 首先 n=m。其次因为 strcmp(str1,str2) >0 所以要先输出str2 再输出 str1+n;
asdf sdfg asdf ghjk
asdfg asdfghjk
HDU 1867 A + B for you again (KMP)
原文:http://blog.csdn.net/xinwen1995/article/details/46123889