【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;
}

相关文章推荐

pku poj 2406

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

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

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

[KMP][后缀数组] poj2406 Power Strings

DescriptionGiven two strings a and b we define a*b to be their concatenation. For example, if a = “a...

poj2406(kmp,后缀数组)

开始是用后缀数组做的,RMQ果断超了内存,全部改用unsigned short结果又超时,后来参考了论文里的方法。   关键思想是设k为最小重复字符串的长度,则s[0,1……n-k-1]=s[k,k+...
  • ysjjovo
  • ysjjovo
  • 2011年07月27日 12:50
  • 881

KMP入门题 Hdu 1711 2594 3746 HUST 1010 Poj 3461 2752 2406 1961 FZU 1901

三道KMP算法的基础题,有关理论可以参考 KMP及其next数组性质学习小记 Poj1961 + Poj2406 - whyorwhnt的专栏 HUST 1010 The Minimum Len...

[POJ 2406] Power Strings (kmp循环节)

链接POJ 2406题意给出一个字符串,输出其最短循环节长度。题解首先说一下循环节,其实每个字符串都是有循环节的,最长的循环节就是它本身。 如果一个字符串s可以写成某个字符串d复制k次得到的,那么d...

POJ 2406 Power Strings(KMP or 后缀数组 dc3板子)

题意:给出一个字符串 问它最多由多少相同的字串组成  思路:有简单的KMP解法点击打开链接 也可以拿KMP做,n 枚举长度i,如果长度i的子串刚好是重复了len/i次,要满足len % i == 0...
  • CillyB
  • CillyB
  • 2017年07月18日 15:21
  • 164

poj2406--Power Strings+KMP求周期

先把结论摆出来:对于长为j的字符串str[1..j],next[j]=k,则令d=j-k;如果j%d==0,则这个字符串是一个 周期串,前d个字符是其最小的循环结,共包含j/d个循环节。 现在来解...
  • acm_lkl
  • acm_lkl
  • 2015年02月07日 15:49
  • 429

POJ -2406 Power Strings(循环节,kmp专题)

A - Power Strings Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Sub...

POJ2406之后缀数组

E - Power StringsDescription Given two strings a and b we define a*b to be their concatenation. For...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【POJ 2406 】
举报原因:
原因补充:

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