2594
题意:给两个字符串str1和str2, 求出是str1的前缀且是str2的后缀的最长的字符串(多组数据,而且长度可以到50000,千万不要有暴力的想法)
查考:对KMP算法的理解,next数组的含义,KMP这里略了,需要请参考
http://www.cppblog.com/oosky/archive/2006/07/06/9486.html
http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html
题意:给两个字符串str1和str2, 求出是str1的前缀且是str2的后缀的最长的字符串
思路:把两个串连接起来得str3,求str3的next,若next[len3]不为零则有这样的串,把str1串前next[len3]个字符输出即可,为零则不存在。
需要一个特殊处理next[len3]大于给定两个串的最大一个时,取最小一个输出(比如 aaaaaa和aaa,只能输出3,你总不能输出大于3的数了吧)
针对现在一些人只会把AC代码直接复制粘贴出来,让人看个半死,本人已做了各种必要注释和题解思路和举例,不懂的可以留言,有不足之处也可以提出来。
#include<iostream>
using namespace std;
char str1[50000 + 10];
char str2[50000 + 10];
char str3[100000 + 10];
int next[100000 + 10];
求str3的next数组
void getNext(char str[],int len)
{
int i=0,j=-1;
next[0]=-1;
while(i<len)
{
if((j==-1)||(str[i]==str[j]))
{
j++;
i++;
next[i]=j;
}
else j=next[j];
}
}
void kmp(int len1, int len2, int len3)
{
if(next[len3]) //当next[len3]的值不为零,则有
{
if(next[len3]>strlen(str1) || next[len3]>strlen(str2)) //当next[len3]大于最大的一个串,取一个短的输出
{
if(len1 > len2) printf("%s %d\n", str2, len2);
else printf("%s %d\n", str1, len1);
}
else //不大于的话
{
str1[next[len3]] = '\0'; //随便拿一个str1或str2截取next[len3]个字符输出
printf("%s %d\n", str1, next[len3]);
}
}
else //当next[len3]的值为零
{
printf("0\n");
}
}
int main()
{
while(cin>>str1>>str2)
{
strcpy(str3, str1);//str3=str1
strcat(str3, str2);//连接
getNext(str3, strlen(str3));
kmp(strlen(str1), strlen(str2), strlen(str3));
}
return 0;
}