| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 14048 | Accepted: 6990 |
Description
Step1. Connect the father's name and the mother's name, to a new string S.
Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S).
Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:)
Input
Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000.
Output
Sample Input
ababcababababcabab aaaaa
Sample Output
2 4 9 18 1 2 3 4 5
题目传送门:POJ 2752 Seek the Name,Seek the Fame
题意:输入一个字符串,找出该字符串的所有前缀的长度,使得该长度的前缀==后缀。说起来挺麻烦的- -其实看一下样例输入输出就能看出来了~
这是一道关于KMP next数组理解的题。设输入的字符串s的长度为len,s本身必满足条件。其他满足条件的子串有这么一个特征:子串的最后一个字符肯定==s串的最后一个字符。(和循环节的意思差不多),那么此时我们就可以运用next数组的性质。如下图:
| 下标: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
| 串: a b a b c a b a b a b a b c a b a b |
| next值: -1 0 0 1 2 0 1 2 3 4 3 4 3 4 5 6 7 8 9 |
所以我们就找出了规律。首先m=len-next[len]。接下来我们的答案就是m组成的数组,m=next[m],直到m到0或者-1为止。
至于为什么会这样呢?就是对于next数组的理解问题。next数组是避免不必要的逐个查找比对,也就代表匹配不成功后向后滑动多少个单位。它也代表了循环节里某个字符在上一个循环节里面出现在母串的位置,我们正是利用了next数组的这个性质。
其实有时候KMP的题搞不懂了,或者自己对next数组理解的还不够透彻,没法灵活运用。我们不妨按照样例先把next数组求出来,就像上表这样对照着看,然后依据样例答案找找规律,一般就能解出来了~ 下面附AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define TEST cout<<"wwwwwwwwwww"<<endl
#define N 1000005
char a[N];
int nextt[N],ans[N];
int len;
void getNext()
{
int i,j;
i=0;
j=-1;
nextt[i]=j;
while(i<len)
{
if(j==-1 || a[i]==a[j])
{
i++;
j++;
nextt[i]=j;
}
else
j=nextt[j];
}
return ;
}
int main()
{
int k,m;
while(scanf("%s",a)!=EOF)
{
k=0;
len=strlen(a);
memset(ans,0,sizeof(ans));
memset(nextt,0,sizeof(nextt));
getNext();
m=nextt[len];
while(m!=-1 && m!=0)
{
ans[k++]=m;
m=nextt[m];
}
for(int i=k-1;i>=0;i--)
printf("%d ",ans[i]);
printf("%d\n",len);
}
return 0;
}
本文详细介绍了一道关于KMP算法的应用题——寻找字符串中既是前缀也是后缀的子串。通过解析题意、阐述KMP算法的核心思想及其next数组的作用,并提供AC代码,帮助读者深入理解KMP算法。
667

被折叠的 条评论
为什么被折叠?



