题目来源:​​http://poj.org/problem?id=2752​

题目描述:

POJ2752 Seek the Name, Seek the Fame(KMP,前后缀匹配_字符串

题意:

给定一个字符串s,求有哪些长度的s的前缀,同时也是s的后缀。

思路:

对于字符串s的第i个字符​​s[i]​​​,​​next[i]​​​定义为字符​​s[i]​​前面最多有多少个连续的字符和字符串s从初始位置开始的字符匹配。那么我们可以从后到前匹配前缀和后缀,如果前缀与后缀匹配,则下一个前缀与后缀匹配的字符串必然在前缀中。不断递归next数组即可求解。

参考代码:

#include <iostream>
using namespace std;
const int N=4e5+10;
#define
#define
int nxt[N],len,ans[N];
string s;
void get_next(string p) {
len = p.size();
int j = 0, k = -1;
nxt[0] = -1;
while (j < len) {
if (k == -1 || p[j] == p[k]) {
nxt[++j] = ++k;
} else {
k = nxt[k];
}
}
}
int main() {
IOS;
while (cin >> s) {
get_next(s);
/*从字符串的尾部开始,下一个前后缀匹配的串只能在与后缀相同的前缀字符串中*/
int sum = 0;
int t = nxt[len - 1];
while (t != -1) {
if (s[t] == s[len - 1])
ans[sum++] = t + 1;
t = nxt[t];
}
for (int i = sum - 1; i >= 0; i--) {
cout << ans[i] << " ";
}
cout << len << end;
}
return 0;
}