POJ-2752

来源:互联网 发布:linux命令行 删除 编辑:程序博客网 时间:2024/06/01 20:48

题目链接:

http://poj.org/problem?id=2406

题目大意:

求该字符串中的前缀中一部分也是后缀的的位置

解题思路:

(网上的解题思路)借用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 <math.h>#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int srcLen = -1;int index = -1;int ans[400000 + 8];char src[400000 + 8];int kmpNext[400000 + 8];void init();void kmp_pre();void KMP();int main(){memset(src, 0, sizeof(src));while (scanf("%s", &src) != EOF){init();KMP();sort(ans, ans + index);/*for (int i = 0; i < srcLen; i++){printf("%d\n", kmpNext[i]);}*/for (int i = 0; i < index; i++){if (i != index - 1){printf("%d ", ans[i]);}else{printf("%d\n", ans[i]);}}}    return 0;}void init(){srcLen = -1;index = -1;memset(ans, 0, sizeof(ans));memset(kmpNext, 0, sizeof(kmpNext));}void kmp_pre(){int i = 0;int j = -1;kmpNext[0] = -1;while (i < srcLen){while (-1 != j && src[j + 1] != src[i+1]){j = kmpNext[j];}if (src[j + 1] == src[i+1]){j++;}i++;kmpNext[i] = j;}}void KMP(){index = 0;srcLen = strlen(src);kmp_pre();int next =srcLen - 1;while (next != -1){ans[index++] = next + 1;next = kmpNext[next];}}


0 0