给定一个字符串s,从小到大输出s中既是前缀又是后缀的子串的长度
从最后一位开始回溯,若s[next[n-1]] == s[n-1],则子串s[0,1,2,...,next[n-1]]是满足条件的子串。然后判断s[next[next[n-1]]] == s[n-1]是否成立,这样一直回滚,直到next[next[.....next[n-1]]] == -1停止,就可以算出所有符合条件的解
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define maxn 1000009
using namespace std;
int n, Next[maxn];
char s[maxn];
vector <int> ans;
void pre ()
{
Next[0] = -1;
Next[1] = 0;
rep (i, 1, n - 1)
{
int j = Next[i];
while (j && s[j] != s[i])
j = Next[j];
Next[i + 1] = s[i] == s[j] ? j + 1 : 0;
}
}
void work (int x)
{
if (Next[x] != -1)
{
ans.push_back (x);
work (Next[x]);
}
}
int main ()
{
while (scanf ("%s", s) == 1) {
n = strlen (s);
pre ();
//rep (i, 0, n - 1) printf ("%d %c\n", i, s[i]); rep (i, 0, n) printf ("%d %d\n", i, Next[i]);
ans.clear ();
work (n);
sort (ans.begin(), ans.end ());
if (!ans.empty ())
{
printf ("%d", ans[0]);
rep (i, 1, (int)ans.size () - 1)
printf (" %d", ans[i]);
}
cout << endl;
}
return 0;
}