kmp最小循环节的求法

其实我一直都没有理解严老师的数据结构中对于next函数求法中的一句话

next 函数求值可以看作是串的模式匹配问题,这句话我一直我不是很理解,我一直把它的过程理解为一个动态规划的过程(有兴趣的话可以参见上一篇文章),后来学长做的一个软件让我明白了


开始的时候,将t串的第一个字母的next值作为0,因为他没有前缀,第二个也是没有后缀,所以他一定是1,但是不能直接将其赋值为1,因为的直接影响着下一个的递推算值,如果相等就i++,j++next[i]=j了,从第三个值开始它就有前缀和后缀了(注意,next[3]函数的意思不是求最大2~3个的后缀等于哪个前缀,而是最大2~2个的最大后缀)所以next[10]=9;

把next的值看作模式匹配问题时候,下面的t串相当于前缀,而上面的t串相当于后缀。

言归正传,我们来谈论,求最小循环串的问题。

我们设想,我们可以利用next函数来求最小循环子串,我们看图


当有循环节的时候,他会有大量的重合,从图中可以看出strlen(T)-j<strlen(T)/2,strlen(T)-j达到最大时候就是只循环两次的时候,就是strlen(T)-j=strlen(T)/2

而没有循环节时候,他的最后strlen(T)-j大于strlen(T)/2,最小的时候就是两次循环的时候

所以,我们以strlen(T)%(strlen(T)-j)是否是0来判断是否是有循环节,然后又用strlen(T)/(strlen(T)-j)来求出最小循环节的大小。

但是细心的读者会发现我们是从0开始的,这样strlen(T)会多一个,并且如果单纯的减1,会因为不符合常理(取余操作过不去)而被判断为没有循环节,所以,我们让j在走一步,这个意思是说到达最后一个的时候,我们不让他返回next[strlen(T)-1]而是返回最后一个j,这样如果最后一个符合条件就会next[strlen(T)-1]++,如果最后一个不符合就会返回next[j],这样不仅解决了strlen(T)的问题,而且解决了只循环两次的问题,例如


这样会返回next[4],也解决了只循环两次的问题。

























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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值