方法一:
题意:求两个串的前缀和后缀最大的长度,
思路:将第一个串作为模式串 第二个作为原串,进行KMP
当 i == len1 作为结束条件
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 50000+10;
char s1[maxn], s2[maxn];
int len1, len2;
int nextval[maxn];
void get_nextval()
{
int i = 0, j = -1;
nextval[0] = -1;
while(i < len2)
{
if(j == -1 || s2[i] == s2[j])
{
if(s2[++i] != s2[++j]) nextval[i] = j;
else nextval[i] = nextval[j];
}
else j = nextval[j];
}
}
void kmp_search()
{
get_nextval();
int i = 0, j = 0;
while(i < len1 && j <= len2)//i == len1 结束
{
if(j == -1 || s1[i] == s2[j]) ++i, ++j;
else j = nextval[j];
if(i == len1)
{
i = i-j;
break;
}
}
if(j == 0) printf("0\n");//如果没有匹配的就 j == 0
else
{
for(int k = i; k < len1; k++) printf("%c", s1[k]);
printf(" %d\n", len1-i);
}
}
int main()
{
while(scanf("%s%s", s2, s1) != EOF)
{
len1 = strlen(s1);
len2 = strlen(s2);
kmp_search();
}
}
方法二:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100000+10;
char a[maxn], b[maxn];
int len1, len2,len3, nextval[maxn];
void get_nextval()
{
int i = 0, j = -1;
nextval[i] = -1;
while(i < len1+len2)
{
if(j == -1 || a[i] == a[j])
{
if(a[++i] != a[++j]) nextval[i] = j;
else nextval[i] = nextval[j];
}
else j = nextval[j];
}
}
int main()
{
while(scanf("%s%s", a, b) != EOF)
{
len1 = strlen(a);
len2 = strlen(b);
len3 = len1 + len2;
strcat(a, b);
get_nextval();
int x = nextval[len3];
if(x)
{
if(x > len1 || x > len2)
{
int m;
if(len1 > len2) m = len2;
else m = len1;
for(int i = 0; i < m; i++)
printf("%c", a[i]);
printf(" %d\n", m);
}
else
{
for(int i = 0; i < x; i++)
printf("%c", a[i]);
printf(" %d\n", x);
}
}
else printf("0\n");
}
}