POJ 2752Seek the Name, Seek the Fame(next数组妙用 + 既是前缀也是后缀)

题目链接

题意:求一个字符串中 前缀 和 后缀 相同的长度

分析: 对于一个字符串他自己的长度肯定是可以的。然后如果满足 前缀 和 后缀相等,那个前缀 最后一个字符 一定 和 该字符串最后一个字符相等,不然不会满足条件。

所以 找 str[len - 1] 的next数组, 对于 next[len - 1] 来看看这个位置 是不是等于最后一个字符,如果相等,那么前 next[len - 1] 一定是可以的, 然后 在判断next[ next[len - 1] ]  是不是等于 str[len - 1] .... 就是一层一层的往前找前缀,判断当前位置 是否等于 最后一个字符

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 using namespace std;
 6 const int Max = 400000 + 10;
 7 char str[Max];
 8 int Next[Max];
 9 int ans[Max];
10 void getNext(int & len)
11 {
12     int i = 0, k = -1;
13     Next[0] = -1;
14     while (i < len)
15     {
16         while (k != -1 && str[k] != str[i])
17             k = Next[k];
18         Next[++i] = ++k;
19     }
20 }
21 int main()
22 {
23     while (scanf("%s", str) != EOF)
24     {
25         int len =strlen(str);
26         getNext(len);
27         int cnt = 0;
28         ans[cnt++] = len;
29         int n = len - 1;
30         while (n != -1)
31         {
32             if (Next[n] != -1 && str[ Next[n] ] == str[ len - 1])
33                 ans[cnt++] = Next[n] + 1;  // 位置 + 1
34             n = Next[n];  // 不断往前找
35         }
36         for (int i = cnt - 1; i > 0; i--)
37             printf("%d ", ans[i]);
38         printf("%d\n", ans[0]);
39     }
40     return 0;
41 }
View Code

 

posted @ 2016-04-22 17:17  zhaop  阅读(294)  评论(0编辑  收藏  举报