首页 > 代码库 > POJ2752 Seek the Name, Seek the Fame next数组应用
POJ2752 Seek the Name, Seek the Fame next数组应用
题目描述
给出一个字符串,求出存在多少子串,使得这些子串既是主串的前缀,又是主串的后缀。从小到大依次输出这些子串的长度。
Sample Input
ababcababababcabab
aaaaa
Sample Output
2 4 9 18
1 2 3 4 5
解题思路:
我们首先知道最大的那个数肯定是主串本身的长度。除去这个最大的应该是next[len].由于我们肯定是由大往小找,而题目要求输出时从小到大输出,所以考虑使用栈结构。找到了next[len]后,主串的前后都有一段长度为next[len]的相同串,故我们考虑next[ next[len] ] 即考虑前缀这边的相同前后缀,由next性质可以知道,前缀的后缀就是后缀的后缀,所以也就是原主串的更小的前后缀相同。
所以一直递归下去就可以了,直到next=0为止。
需要注意的是,next数组不能开优化,应该给予next最本质的定义,否则会出错。
代码如下
#include <cstdio> #include <stack> #include <cstring> using namespace std; void GetNext(char* p,int next[]) { int pLen = strlen(p); int k = -1;//k记录的是next[j] next[0] = k; int j = 0; while (j < pLen) { /** next[j]=-1时,next[j+1]肯定是0;p[j]=p[k]时,next[j+1]=next[j]+1 */ if (k == -1 || p[j] == p[k]) { ++k; ++j; /* if(p[j] != p[k]) */next[j] = k; // else next[j] = next[k]; } else k = next[k]; } } const int maxn = 400010; char s[maxn]; int next[maxn]; stack<int> p; int main() { while(scanf("%s",s) != EOF) { GetNext(s,next); int k = strlen(s); while(next[k] > 0) { p.push(next[k]); k = next[k]; } while(!p.empty()) { printf("%d ",p.top()); p.pop(); } printf("%d",strlen(s)); printf("\n"); } return 0; }
POJ2752 Seek the Name, Seek the Fame next数组应用
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。