例题:
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
string str1,str2;
int ne[N];
int n,len;
void init(string p)
{
for(int i=2,j=0;i<=n;i++)
{
while(j&&p[i]!=p[j+1])
{
j=ne[j];
}
if(p[i]==p[j+1])
{
j++;
}
ne[i]=j;
}
}
int kmp(string p,string s)
{
int i,j;
for( i=1,j=0;i<=len;i++)
{
while(j&&s[i]!=p[j+1])
{
j=ne[j];
}
if(s[i]==p[j+1])
{
j++;
}
if(j==n)
{
return i-n+1; //返回第一个匹配的位置
}
}
//如果不能完全匹配,就返回第一个
return i-j;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>str1>>str2;
bool f1=false,f2=false;
int len1=str1.size();
int len2=str2.size();
string s1,s2;
s1=str1,s2=str2;
str1=" "+str1;
str2=" "+str2;
//①str1是模式串,str2是主串
n=len1;
len=len2;
init(str1);
int pos=kmp(str1,str2);
if(pos==n+1)
{
f1=true;
}
int l1;
//如果是完全匹配
if(pos+n-1<=len)
{
cout<<s2<<endl;
return 0;
}
else //否则是前缀和主串后缀匹配
{
l1=len-pos+1;
}
n=len2;
len=len1; //主串变成了第一个字符串
memset(ne,0,sizeof ne);
init(str2);
pos=kmp(str2,str1);
if(pos==n+1)
{
f2=true;
if(f1&&f2)
{
cout<<s1+s2<<endl;
return 0;
}
}
int l2;
//如果完全匹配
if(pos+n-1<=len)
{
cout<<s1<<endl;
return 0;
}
else //否则是前缀和主串后缀匹配
{
l2=len-pos+1;
}
if(l1>=l2)
{
cout<<s2;
for(int i=l1+1;i<=len1;i++)
{
cout<<str1[i];
}
return 0;
}
else{
cout<<s1;
for(int i=l2+1;i<=len2;i++)
{
cout<<str2[i];
}
}
return 0;
}