KMP算法求循环节,为什么能求循环节

众所周知,KMP算法可以求最小循环节,为什么可以求循环节呢?

博主之前对KMP算法的理解不够深入,最近突然又想起来了,就深入研究了一下。

 KMP算法中最重要的就是next数组,next[i]表示是字符串中所有以 i 为结尾的非前缀子串中与前缀能匹配的长度的最大值。可能有点绕,缕一缕吧,这就是next[ ]数组的定义而已。

我们求最小循环节也是利用next[ ]数组求的。假设字符串是一个循环字符串,可以有一个循环节循环多次得到(假设多于一次),不妨假设循环节是str1,原来的字符串肯定是由循环节循环而来,即string=str1str1...str1,如果字符串长度为len,根据next[ ]数组的定义,next[len]就是以字符串结尾为结尾的非前缀与前缀匹配的最大长度,如果这个字符串能由一个循环节循环多次得到,那么next[n]中一定包含了至少一次循环节,而且是去掉了从头开始的第一个循环节后的整个字符串。自己在本子上画一下就好了。对齐方式肯定是下图这个样子,每一个方框都是一个循环节。

因为我们设的是最小循环节,如果认为有其他方法,那么一定可以将第二个字符串对齐的时候向前移动,如果这样的话那么它肯定不是最小循环节。既然这样,最小循环节长度就是len - next[len],如果能由它循环多次得来,一定满足满足以下条件。

len % (len - next[len]) == 0

如果len - next[len] == len 说明整个字符串是一个循环节,特判一下就好了。当然这个求的最小循环节,次小的循环节应该是len - next[next[len]],以此类推,当然需要判断一下啦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值