题意:给出两个字符串s1,s2,找到一个最短的字符串s,使得s1是它的子串,s2也是它的字串。
方法:用KMP,首先判断s1是否是s2的字串,若是,则直接输出s2的长度,,即s2就是我们找的s字符串。同理判断s2是否是s1 的字串。
若都不是,,则判断s1 的前缀与s2的后缀最大重合部分k1,s2的前缀与s1后缀最大重合部分k2,判断k1与k2的大小,然后用s1的长度加s2的长度减去k1,k2中较大者。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
#define maxn 1000009
char a[maxn];
char b[maxn];
int next[maxn];
void get_next(char *a)
{
int i=0,j=-1;
next[0] = -1;
while( a[i] )
{
if(j == -1 || a[i]==a[j])
{
if(a[++i]!=a[++j]) next[i] = j;
else next[i] = next[j];
}else j = next[j];
}
}
int KMP(char *a,char *b)///用a的前缀去匹配b的后缀
{
int i=0,j=0,lena = strlen(a),lenb = strlen(b);
get_next(a);
while(j < lenb && i < lena )
{
if(i==-1 || a[i]==b[j]) ++i,++j;
else i = next[i];
}
if(i>=lena) return -3;
else return i;
}
int main()
{
int T;cin>>T;
while(T--){
scanf("%s%s",a,b);
int k1 = KMP(a,b);
int k2 = KMP(b,a);
if(k1==-3) printf("%d\n",strlen(b));
else if(k2==-3) printf("%d\n",strlen(a));
else {
printf("%d\n",strlen(a)+strlen(b)-max(k1,k2));
}
}return 0;
}
这是我发表的第一篇KMP,因为刚学的时候自己都不怎么了解KMP,,不敢误人子弟啊。。