HDU1841 Find the Shortest Common Superstring (KMP两字符串的首尾连接)

来源:互联网 发布:手机视频播放网页源码 编辑:程序博客网 时间:2024/06/05 18:05

题意:给我们两个字符串,求解一个最短的字符串,两个字符串连接的时候相同的可以
重叠,例如:“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
随笔:在解决一些问题时,当感觉自己无能为力或心烦意乱时,不要急于前进,那样只会令我们感到枯燥无味,甚至厌烦,有时我们就当作是在读他人的一个故事,或者是在倾听他人的一些心声,即使这些对我们没啥用,但慢慢你会重新开始奋斗,并向着自己之前所定下的目标重新前进,不要因为一时的感慨而放弃或者承诺。

阅读全文
1 0
原创粉丝点击