KMP循环节

首先求失配函数

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] )



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值