KMP循环节
来源:互联网 发布:老是找不到东西知乎 编辑:程序博客网 时间:2024/04/30 11:49
首先求失配函数
rep(i,1,n-1){ int j=f[i]; while(j&&s[i]!=s[j]) j=f[j]; f[i+1]=(s[i]==s[j])?j+1:0; }
f数组在求解的过程中,用到了KMP的思想,当前失配了,就回溯到上一个next,请见 j=f[j] ,先说个结论,如果到位置 i ,如果有 i%(i-f(i))==0 , 那说明字符串开始循环了,并且循环到 i-1 结束,为什么这样呢?
我们先假设到达位置 i-1 的时候,字符串循环了(到i-1完毕),那么如果到第i个字符的时候,失配了,根据f数组的求法,我们是不是得回溯?
然而回溯的话,由于字符串是循环的了(这个是假定的),f[i] 是不是指向上一个循环节的后面一个字符呢??
是的,上一个循环节的末尾是 f[i]-1 ,然后现在循环节的末尾是 i-1 ,然么循环节的长度是多少呢?
所以,我们有 (i - 1) - ( f[i] - 1 ) = i - f[i] 就是循环节的长度(假设循环成立的条件下),但是我们怎么知道这个循环到底成立吗?
现在我们已经假设了 0————i-1 循环了,那么我们就一共有i 个字符了,如果有 i % ( i - f[i] ) == 0,总的字符数刚好是循环节的倍数,那么说明这个循环是成立的。
注意还有一点,如果 f[i] == 0,即使符合上述等式,这也不是循环的,举个反例
0 1 2 3 4 5
a b c a b d
-1 0 0 0 1 2
下标为1,2,3的next值均为0,那么 i%(i-f[i])=i%i==0,但是这个并不是循环。
解释完毕,然后再来看下,为什么求出来的循环节长度是最小的呢?
因为next数组失配的时候,总是回溯到最近的循环节,所以i-f[i]就是最小的循环节长度
为什么求出来的循环次数是最多的呢?
循环节长度是最小的了,那么循环次数肯定是最多的了。
总结一下,如果对于next数组中的 i, 符合 i % ( i - f[i] ) == 0 && f[i] != 0 , 则说明字符串循环,而且
循环节长度为: i - f[i]
循环次数为: i / ( i - f[i] )
- HDU3746-KMP循环节
- kmp循环节
- hdu1358 KMP循环节
- KMP循环节
- KMP找循环节
- 【KMP】 hdu3746 kmp求循环节长度
- hdu1358(KMP+最小循环节)
- hust1010TheMinimumLength(kmp,循环节)
- poj1961 KMP求循环节
- 【KMP】与字符串循环节
- KMP求循环节问题
- 【KMP】【HDU3746】【最小循环节】
- HDU 3746 kmp循环节
- Period (HDU_1358) KMP+循环节
- hdu 1358 KMP循环节
- KMP(最小循环节)
- Period--KMP,最小循环节
- poj1961 KMP(循环节)
- ServletConfig和ServletContext接口
- Ubuntu16.04下python+PyCharm开发环境的搭建
- [dfs 离线] Hillan模拟赛 C.可持久化的书橱
- ecshop数据库表6(ecs_admin_user)管理表
- Caffe中crop_layer层的理解和使用
- KMP循环节
- java.io.IOException: Too many open files
- [人工智能]人工智能、机器学习和深度学习三者之间的关系
- 用友uap开发报错:流程平台缓存中不存在该单据或交易类型=xxx
- String8StringToInteger
- android 开启service
- Effective Java学习笔记(一) 创建和销毁对象
- android判断用户的 网络类型
- PHP中include()与require()的区别说明