0
点赞
收藏
分享

微信扫一扫

POJ2752 Seek the Name, Seek the Fame【KMP】


题目链接:

​​http://poj.org/problem?id=2752​​


题目大意:

给定一个字符串S,计算出所有可能的前缀-后缀字符串的长度。前缀-后缀字符串指的是S的

子串不仅是S的前缀,还是S的后缀。比如S = "alala",前缀-后缀字符有{"a","ala","alala"}。


思路:

KMP算法的应用。在KMP算法中,当字符串匹配失败时,模式串的指针并没有指向0从头比

较,而是指向了一个特定的位置,因为这个Next[j]指向的位置pos前长度为Next[pos]的子

串,同模式串第j位前的长度为Next[j]的子串是相同的。

即S[0]~S[Next[len]]一定与S[len-1-Next[len]]~S[len-1]匹配。

为了找到既能做前缀又能做后缀的子串,那么可以找Next[len]前的长度为Next[len]的子串,

这个子串一定是前缀,又由Next函数的性质可知,这个前缀字符串长度和字符串长度为

Next[len]的后缀是相同的,这样就找到除S本身以外所有满足条件的子串。也可以找到所有

满足条件的子串长度。


AC代码:


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 400010;

char str[MAXN];
int Next[MAXN],ans[MAXN],len;
void GetNext()
{
int i = 0,j = -1;
Next[0] = -1;
while(i < len)
{
if(j == -1 || str[i] == str[j])
{
i++,j++;
Next[i] = j;
}
else
j = Next[j];
}
}

int main()
{
while(cin >> str)
{
len = strlen(str);
GetNext();
ans[0] = len;
int id = 1,i = len;
while(Next[i] > 0)
{
ans[id++] = Next[i];
i = Next[i];
}

for(i = id-1; i >= 0; i--)
cout << ans[i] << ' ';
cout << endl;
}


return 0;
}



举报

相关推荐

0 条评论