hdu1358(KMP,next数组性质)
2017-02-12 00:10
211 查看
题目链接:Period
题目大意:任给一个字符串T,对于其长度为i的前缀,S=T[0,1,..i-1]
如果存在一个比S更小的前缀A使得S=AA...A,即S=A^K(K>1),则满足题目要求,输出i和和k
如图
![](http://images.cnitblog.com/i/521482/201403/071511224259562.jpg)
当i=2时,
B[0]=B[1]
j= i-next[i]=1,i%j=0,循环节i/j=2
当i=6时,
B[0,1,2]=B[3,4,5]
j=i-next[i]=3,i%j=0,循环节i/j=2
当i=9时,
B[0,1,2,3,4,5]=B[3,4,5,6,7,8]
j=i-next[i]=3,i%j=0,循环节i/j=3
当i=12时
B[0,1,2,3,4,5,6,7,8]=B[3,4,5,6,7,8,9,11]
j=i-next[i]=3,i%j=0,循环节i/j=4;
![](https://img-blog.csdn.net/20170211233512708?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcG10MTIzNDU2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
当i=2时,
B[0]=B[1]
j= i-next[i]=1,i%j=0,循环节i/j=2
当i=12时
B[0,1,2,3,4,5]=B[6,7,8,9,10,11]
j=i-next[i]=6,i%j=0,循环节i/j=2;
分析
KMP算法中,next[j]应该是所有满足B[0...next[i]-1]=B[i-next[i]...i-1]的最大值
在第一个例子中
B[0,1,2,3,4,5,6,7,8]=B[3,4,5,6,7,8,9,11]
B[0 1 2 3 4 5 6 7 8]
B[3 4 5 6 7 8 9 10 11]
012=345 345=678 678=910 11
如此就得到路循环节
对于B[ 0 1 2 ... next[i]-1]
B[ i-next[i] i-next[i]+1 i-next[i]+2 ... i-1]可以推出B[0,1,...,i-next[i]-1]为循环节
注意,k=0或1时情况,此时next[i]=1或next[i]=0
题目大意:任给一个字符串T,对于其长度为i的前缀,S=T[0,1,..i-1]
如果存在一个比S更小的前缀A使得S=AA...A,即S=A^K(K>1),则满足题目要求,输出i和和k
如图
![](http://images.cnitblog.com/i/521482/201403/071511224259562.jpg)
当i=2时,
B[0]=B[1]
j= i-next[i]=1,i%j=0,循环节i/j=2
当i=6时,
B[0,1,2]=B[3,4,5]
j=i-next[i]=3,i%j=0,循环节i/j=2
当i=9时,
B[0,1,2,3,4,5]=B[3,4,5,6,7,8]
j=i-next[i]=3,i%j=0,循环节i/j=3
当i=12时
B[0,1,2,3,4,5,6,7,8]=B[3,4,5,6,7,8,9,11]
j=i-next[i]=3,i%j=0,循环节i/j=4;
当i=2时,
B[0]=B[1]
j= i-next[i]=1,i%j=0,循环节i/j=2
当i=12时
B[0,1,2,3,4,5]=B[6,7,8,9,10,11]
j=i-next[i]=6,i%j=0,循环节i/j=2;
分析
KMP算法中,next[j]应该是所有满足B[0...next[i]-1]=B[i-next[i]...i-1]的最大值
在第一个例子中
B[0,1,2,3,4,5,6,7,8]=B[3,4,5,6,7,8,9,11]
B[0 1 2 3 4 5 6 7 8]
B[3 4 5 6 7 8 9 10 11]
012=345 345=678 678=910 11
如此就得到路循环节
对于B[ 0 1 2 ... next[i]-1]
B[ i-next[i] i-next[i]+1 i-next[i]+2 ... i-1]可以推出B[0,1,...,i-next[i]-1]为循环节
注意,k=0或1时情况,此时next[i]=1或next[i]=0
#include <stdio.h> #include <string.h> const int maxn=1000005; char T[maxn]; int next[maxn]; void getNext(int len) { int i=0,k=-1; next[0]=-1; while(i<len){ if(k==-1||T[i]==T[k]){ next[++i]=++k; } else{ k=next[k]; } } } int main() { //freopen("in.txt","r",stdin); int len; for(int c=1;;c++){ scanf("%d",&len); if(len==0)break; printf("Test case #%d\n",c); scanf("%s",T); getNext(len); for(int i=2;i<=len;i++){ if(next[i]==0||next[i]==-1)continue; int j=i-next[i]; if(i%j==0){ printf("%d %d\n",i,i/j); } } printf("\n"); } return 0; }
相关文章推荐
- KMP (next数组的性质及证明)
- POJ 2752+KMP+利用next数组性质求出所有相同的前缀和后缀
- KMP及其next数组性质学习小记 Poj1961 Period
- poj 2185 Milking Grid(KMPnext数组的性质+lcm)
- KMP的next数组性质运用
- HDU 1358(KMP:next数组性质)
- KMP的next数组性质运用
- hdu1358 KMP-next数组的应用
- [KMP-NEXT数组性质]POJ 2752 Seek the Name, Seek the Fame
- POJ2752_通过kmpNext数组的性质求一个字符串的公共同前后缀
- kuangbin专题十六 POJ2752(好题) KMP的next数组性质的考察
- hdu1358 kmp的next数组
- POJ 2406(KMP next数组性质)
- KMPnext数组循环节理解 HDU1358
- HDU 3336 Count the string(kmp next数组的性质)
- 【给数学不好的人的KMP】字符匹配教程(一)next数组的理解
- hdu 3336、4763、2594 kmp next数组的理解、模板题
- hdu1358 Period KMP之next函数灵魂 KMP的周期 周期 周期
- POJ 1961 Period KMP(next数组应用)
- KMP之next[]数组的求解