Seek the Name, Seek the Fame POJ

 

 

题意:给出一个字符串,问字符串中存在多少子串,使得这些子串既是字符串的前缀,又是字符串的后缀,要求从小到大依次输出这些子串的长度。

思路:根据 next 数组的定义,可以得到前缀 next[len] 长度的子串与后缀 next[len] 长度的子串相同,因此求出 len 处的 next 值,然后向下递归即可得到答案

next数组:next[i]表示以i为终点的前缀的最长相同前后缀长度

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 4e5 + 10;
 7 char s[maxn];
 8 int l;
 9 int nxt[maxn];
10 int ans[maxn];
11 void work() {
12     for (int i = 2, j = 0; i <= l; i++) {
13         while (j > 0 && s[i] != s[j + 1])
14             j = nxt[j];
15         if (s[i] == s[j + 1]) j++;
16         nxt[i] = j;
17     }
18 }
19 
20 
21 
22 int main() {
23     //freopen("in","r",stdin);
24     while(scanf("%s", s + 1)!=EOF) {
25         l = strlen(s + 1);
26         work();
27        // for(int i = 1; i <= l; i++)
28         //    cout << nxt[i] << " ";
29        int i = l;
30        int c = 0;
31        while(i){
32            ans[c++] = nxt[i];
33            i = nxt[i];
34        }
35        for(int i = c - 2; i >= 0; i--)
36            printf("%d ",ans[i]);
37        printf("%d
",l);
38     }
39     return 0;
40 }
View Code
原文地址:https://www.cnblogs.com/xcfxcf/p/12742103.html