题意
在字符串S中寻找出所有字串,它即是这个字符串的前缀,也是这个字符串的后缀,输出它们的长度。
知识储备与解题思路
KMP中的next数组的含义,对于以i-1为结尾的子串,T[0, next[i]-1] 与 T[i-next[i], i-1]是相等的,且这两个相等的字符串是这个字串的前后缀,以样例为例分析以下。
字符串 ababcababababcabab
next[i] 001201234343456789
next[n]是9,那么前后9个必相同,next[next[n]]代表的字符串一定是下一个满足条件的子串。自行好好理解一下就行,写不明白 = =。
代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 400010;
char s[MAX];
int n, f[MAX],ans[MAX];
void failure_function(){
f[0] = f[1] = 0;
for(int i=1; i<n; i++){
int j = f[i];
while(j && s[i] != s[j]) j = f[j];
f[i+1] = (s[i] == s[j]) ? j + 1 : 0;
}
}
int main(){
while(scanf("%s",s) == 1){
n = strlen(s);
failure_function();
int t = 0, i = n;
while(f[i] > 0){
ans[t++] = f[i];
i = f[i];
}
for(int i = t - 1; i >= 0; i--)
printf("%d ",ans[i]);
printf("%d\n",n);
for(int i=1; i<=n; i++)
cout << f[i] << " ";
cout << endl;
}
return 0;
}