题意:给我们两个字符串,求解一个最短的字符串,两个字符串连接的时候相同的可以
重叠,例如:“alba” 和“bacau”重叠在一起的最短串是 “albacau”。
解析:最初看到这题时,是将两个串连接起来,用strcat函数,然后利用kmp求它的
循环子段,这就是我的数组为啥开的两倍,但后来发现对于“abaa”“a”或者“aaaba”
“aa”….类似这一类,它的处理就会出错,后来将它分开处理了,但发现分开后又不好连接了,
于是上网搜寻博客,看了前面几篇博客,他们的next数组的都是从-1开始,然自己从最初开始是
next数组是从0开始的,鉴于网上next数组从0开始较少所以有了此次的内容,一些过程
在代码里有解释。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAX=2e6+10;
int T;
char str1[MAX*2],str2[MAX*2];
char str[MAX*2];
int ans;
int str1_len,str2_len;
int Next[MAX*2];
void kmp_next(char str[],int len)//Next的数组,不了解的可以模拟下过程,都是这样过来的。
{
Next[0]=0;
for(int i=1;i<len;i++)
{
int k=Next[i-1];
while(k!=0&&str[i]!=str[k])
k=Next[k-1];
if(str[i]==str[k]) Next[i]=k+1;
else Next[i]=0;
}
}
int KMP(char str1[],char str2[],int len1,int len2 )
{//返回处理两个字符串重复字符的个数,比如“abcdef”“efcd”,此时返回的就是ef的个数2。
int k=0;
for(int i=0;i<len1;i++)
{
while(k!=0&&str1[i]!=str2[k]) k=Next[k-1];
if(str1[i]==str2[k]) k++;
if(k==len2) return len2;
}
return k;
}
//下面两次使用KMP这个函数,其目的是第一次以str1为首,第二次以str2为首,从而找出两种结果最大
//的重复个数
int main()
{
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%s%s",str1,str2);
str1_len=strlen(str1);
str2_len=strlen(str2);
memset(Next,0,sizeof(Next));
kmp_next(str1,str1_len);
ans=KMP(str2,str1,str2_len,str1_len);
memset(Next,0,sizeof(Next));
kmp_next(str2,str2_len);
ans=max(ans,KMP(str1,str2,str1_len,str2_len));
ans=str1_len+str2_len-ans;//找到最大的重复个数后,用两个字符的总长度减去重复
printf("%d\n",ans); //的字符个数就可以了。
}
return 0;
}
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1841
随笔:在解决一些问题时,当感觉自己无能为力或心烦意乱时,不要急于前进,那样只会令我们感到枯燥无味,甚至厌烦,有时我们就当作是在读他人的一个故事,或者是在倾听他人的一些心声,即使这些对我们没啥用,但慢慢你会重新开始奋斗,并向着自己之前所定下的目标重新前进,不要因为一时的感慨而放弃或者承诺。