A + B for you again
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9063 Accepted Submission(s): 2194
Problem Description
Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such as “asdf” and “sdfg”, the result of the addition between them is “asdfg”, for “sdf” is the tail substring of “asdf” and the head substring of the “sdfg” . However, the result comes as “asdfghjk”, when you have to add “asdf” and “ghjk” and guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.
Input
For each case, there are two strings (the chars selected just form ‘a’ to ‘z’) for you, and each length of theirs won’t exceed 10^5 and won’t be empty.
Output
Print the ultimate string by the book.
Sample Input
asdf sdfg asdf ghjk
Sample Output
asdfg asdfghjk
Author
Wang Ye
Source
Recommend
题目意思很简单,不过有点坑的地方在于最后输出的字符串要是最短的并且字典序最小的,
用kmp去找两个字符串相互重叠(a的后缀和b的前缀或者b的前缀和a的后缀)的部分长度是多少,如果a和b 相互重叠的部分一样长,就比较a和b谁的字典序小,然后输出小的那个就好了.
#include <iostream>
#include<string>
#include<cstring>
using namespace std;
string a,b;
int nexts[100005];
void getnext(string b)
{
memset(nexts,0,sizeof(nexts));
nexts[0]=-1;
int k=-1;
int i=0;
int len=b.size();
while(i<len)
{
if(k==-1||b[i]==b[k])
{
++i,++k;
nexts[i]=k;
}
else
k=nexts[k];
}
}
int kmp(string a,string b)
{
getnext(b);
int cnt=0;
int j=0;
int i=0;
int lena=a.size();
int lenb=b.size();
while(i<lena)
{
if(j==-1||a[i]==b[j])
++i,++j;
else
j=nexts[j];
}
return j; // 返回匹配到的最大的长度
}
int main()
{
while(cin>>a>>b)
{
int len1=kmp(a,b);
int len2=kmp(b,a);
if(len1==len2){
if(a<b)
cout<<a<<b.c_str()+len1<<endl; //巧妙的一点:string 转char* 类型后,直接加上可重叠的长度即可输出重叠后的字符
else
cout<<b<<a.c_str()+len2<<endl;
}
else
if(len1>len2){ //最后的结果长度尽可能短.
cout<<a<<b.c_str()+len1<<endl;
}
else
cout<<b<<a.c_str()+len2<<endl;
}
return 0;
}