【POJ 2406 】

原创 2013年12月04日 11:23:02

题目链接:http://poj.org/problem?id=2406

设文本为T={t1,t2...tn},模式为P={p1,p2...pn},则KMP算法的大概思想就是提前计算出在字符处匹配中遇到前q个字符匹配而第q+1个字符不匹配时,模式P需要移动的位置数。在算法导论中,引入了一个数组π,用于保存这样的信息。π[m]的含义就是既是Pm的前缀又是Pm的真后缀的最大子串长度。之所以是“真”后缀,是因为如果非真后缀的话,此时已经匹配了。π的含义如下

i      1 2 3 4 5 6 7  8

pi    a b a b a b a b

π[i]  0 0 1 2 3  4 5 6

而需要特别注意的是算法导论中的下标是从1开始的,这是和π中元素的含义(即上面所说)相匹配的,这种情况下,如果遇到不匹配的字符时,移动量的计算公式为最后一个匹配字符的索引(设为q)-π[q]。如

1 2 3 4 5 6  7

a b a b a b c

a b a b a b d

那么此时需要移动的量为6-π[6]=6-4=2。而在具体的代码实现时,我们需要计算的是next数组,next数组的计算结果和π有一点点的不相同,因为在代码实现中,我们的下标都是从0开始的。仍以上面的例子为例:

i           0  1 2 3 4 5 6  7  8

pi         a  b a b a b a b

next[i]  -1  0 0 1 2 3  4 5 6//注意next中-1后有两个0,看了几个网上的答案,都是一个,需要特别注意。

此时,如果遇到不匹配的字符时,计算公式为第一个不匹配字符的索引(设为q)-next[q]。如:

0  1 2 3 4 5  6

a  b a b a b c

a  b a b a b d

-1 0 0 1 2 3 4

则需要移动的量为6-4=2。而此时的next数组的含义也不再是算法导论中真后缀的最大前缀子串的长度了。

 

 

目前还不太理解。。

问题是:如何快速找出S的最小循环周期(循环节)呢?
Len是s的长度

给出结论:如果len%(len-next[len-1])==0,则字符串中必存在最小循环节,且循环次数即为 len/(len-next[len-1])

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[1000001];
int next[1000001];
void getnext(char *p,int *next){
	int len=strlen(p);
	int i=0,k=-1;
	next[0]=-1;
	while(i<len){
		if(k==-1 || p[i]==p[k]){
			i++;
			k++;
			next[i]=k;
		}
		else
			k=next[k];
	}
}
int main(){
	while(1){
		scanf("%s",s);
		if(s[0]=='.')
			break;
		getnext(s,next);
		int len=strlen(s);
		if(len%(len-next[len])==0)
			printf("%d\n",len/(len-next[len]));
		else
			printf("1\n");
	}
	return 0;
}

POJ2406之后缀数组

E - Power StringsDescription Given two strings a and b we define a*b to be their concatenation. For...
  • superxtong
  • superxtong
  • 2016年08月01日 01:42
  • 1188

KMP算法的经典例题(poj 3461、poj 2752、poj 2406、poj1961)

传送门:POJ-3461 最简单的KMP题,找出第一个字符串在第二个字符串中出现次数。 #include #include #include #define Memset(x, a) mems...
  • guhaiteng
  • guhaiteng
  • 2016年08月03日 23:48
  • 2780

一位ACMer过来人的心得 POJ测试数据合集

转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6642573     最近AC题:2528   更新时间:201...
  • Irene_ruru
  • Irene_ruru
  • 2015年06月08日 15:33
  • 2888

pku poj 2406

  • 2009年08月04日 16:57
  • 555B
  • 下载

POJ2406之后缀数组

E - Power StringsDescription Given two strings a and b we define a*b to be their concatenation. For...
  • superxtong
  • superxtong
  • 2016年08月01日 01:42
  • 1188

poj2406—KMP next数组的性质求最小周期

题目大意:给出一个字符串,求它最多有几个连续子串构成 分析:KMP求最小周期——结论:如果一个字符串有最小周期,那么最小周期为n-next[n] 考虑整个串,根据next数组的定义,前后匹配并且前...
  • zz_ylolita
  • zz_ylolita
  • 2016年02月10日 22:37
  • 362

POJ 2406 Power Strings(后缀数组[连续重复子串])

POJ 2406 Power Strings(后缀数组[连续重复子串])
  • queuelovestack
  • queuelovestack
  • 2016年10月27日 10:19
  • 661

poj 1961 2406 让你彻底理解KMP的next[]数组的两个题目

两题运用kmp思路基本上是一样的,都是从头开始找相同前缀的   运用next数组原理,让你充分理解,即使不理解,你也记住了,哈哈 poj 2406 Power Strings...
  • Summer__show_
  • Summer__show_
  • 2016年02月01日 00:12
  • 366

POJ 2406(连续重复子串)

题目链接:POJ 2406 Power Strings题目大意:给一个字符串L,已知该字符串由某个字符串S重复r次得到,求r最大值。 解题思路:法一:- 可以使用后缀数组解决。 - 想法非常简单,就是...
  • nixinyis
  • nixinyis
  • 2017年02月03日 11:03
  • 139

POJ 2406 Power Strings

题目大意: 注释代码: 无注释代码: 单词解释:
  • u013569656
  • u013569656
  • 2014年04月14日 19:26
  • 393
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【POJ 2406 】
举报原因:
原因补充:

(最多只允许输入30个字)