给定一个字符串s,从小到大输出s中既是前缀又是后缀的子串的长度。
此题非常简单,借用KMP算法的next数组,设s的长度为n,则s串本身必定满足条件。其他满足条件的子串都有个特征,就是该子串的最后一个字符肯定与s的最后一个字符相同。这正是next数组发挥作用的时候。从n - 1位既最后一位开始回滚,若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 <cstdio> #include <cstring> using namespace std; int Next[400005]; char str[400005]; int ans[400005]; int cnt; int len; void getNext() { Next[0] = -1; int i = 0, j = -1; while (i < len) { if (j == -1 || str[i] == str[j]) { ++i; ++j; Next[i] = j; } else j = Next[j]; } } int main() { while (scanf("%s", str) != EOF) { len = strlen(str); getNext(); cnt = 0; int t = Next[len - 1]; while (t != -1) { if (str[t] == str[len - 1]) ans[cnt++] = t + 1; t = Next[t]; } for (int i = cnt - 1; i >= 0; --i) { printf("%d ", ans[i]); } printf("%d\n", len); } return 0; }