poj 2752
来源:互联网 发布:sql注入攻击与防御pdf 编辑:程序博客网 时间:2024/06/15 05:00
题目概述
给定一个字符串str,求所有符合条件的前缀长度,使此长度的前缀与等长的后缀匹配
时限
2000ms/6000ms
输入
每行一个字符串,输入到EOF为止
限制
1<=字符串长度<=4e5
输出
每行若干个数,为符合条件的前缀长度按升序排列,每个数字后跟一空格
样例输入
ababcababababcabab
aaaaa
样例输出
2 4 9 18
1 2 3 4 5
讨论
字符串,kmp算法中next数组的应用,只要知道next数组中每个值的意义是由其前面的字符构成的子串中,互相匹配的最长前缀后缀的长度,也就是这个题所求的东西,比如第一组样例,从最后一个字符开始看next数组(假设已经求得next数组),字符串长18,next[18]为9,说明整个字符串最长长度为9的前缀和后缀是匹配的,下面看看有没有短一点的,既然长度9的前缀后缀都一样,那整个字符串的其他前缀也就是长度9的前缀的前缀,整个字符串的其他后缀也就是长度9的后缀的后缀,也就是长度9的前缀的后缀,好绕口……但确实如此,因而接下来只要考察长度9的前缀(其实考察后缀也一样)即可,长度9,next[9]为4,字符串被分成三部分,前缀,长度4,中间没用的部分,长度1,后缀,长度4,然后遵循之前的思想,继续递归找下去,直到某个next的值为0为止,最后输出
等一下,为什么next数组的意义是这个?实际上因为kmp的思想就是这个,每次不要让模式串的指针都回溯到头,所以需要找到模式串自己和自己匹配的长度,确切说是对于模式串所有前缀,找出(前缀的)最长的前缀,使其与(前缀的)这个长度的后缀匹配,当然,找到的长度自然不能(也不可能)是自身长度,这也就是为什么上面的例子中next[18]为9,而不是next[17](str[17]是字符串的最后一个非空白字符,str[18]是\0),所以说,人家算法就这么设计的,意义自然是这个
题解状态
2632K,125MS,C++,702B
题解代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>//这些都是计算几何的遗留产物 不用管他们using namespace std;#define INF 0x3f3f3f3f#define MAXN 400003#define memset0(a) memset(a,0,sizeof(a))#define EPS 1e-8int Next[MAXN];//next数组 不是next因为iterator头文件中有函数next 使得迭代器向容器后方移动若干个位置 真不巧char str[MAXN];//string 原始字符串int stk[MAXN], top;//stack 数组模拟栈及其栈顶 因为要升序输出void calNext(int len)//calculate_next 额也不明白其正确性 不过所幸不难背过 一般也不会对这个函数下手{ int p = 0, i = -1; Next[0] = -1; while (p < len) if (i == -1 || str[p] == str[i]) Next[++p] = ++i; else i = Next[i];}int main(void){ //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); while (~scanf("%s", str)) {//input int len = strlen(str);//读取长度备用 calNext(len); while (len) { stk[top++] = len;//首先字符串自身的长度必然符合条件 但是next数组中不会有这个值 因而先把自己压栈 len = Next[len];//然后再将字符串划分寻找较小的前缀长度 } for (; top; top--) printf("%d ", stk[top - 1]);//output//退栈输出 printf("\n");//output }}
EOF
- POJ 2752
- poj 2752
- poj 2752
- POJ 2752
- poj 2752
- POJ 2752
- poj(2752)
- POJ 2752
- poj 2752
- POJ 2752
- poj 2752
- POJ-2752
- POJ 2752
- POJ-2752
- poj 2752
- Poj 2752
- poj 2752
- POJ 2752
- 全文检索 Lucene(4)
- HDU 4902 Nice boat 线段树(区间更新)
- Mybatis分页实现
- 沉浸式状态栏实现(适合新手)
- 去交错Deinterlace算法介绍
- poj 2752
- 让vs2013支持Makefile语法高亮
- Http——Android中HttpURLConnection使用详解
- struts文件的上传
- C++之多线程网络安全的笔记
- C语言 作业三 数组专题
- 进阶项目9-玩转日期和时间
- oj 4118 开餐馆
- 进程守护