众所周知,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]],以此类推,当然需要判断一下啦。
来源:CSDN
作者:correct!
链接:https://blog.csdn.net/weixin_43701790/article/details/104540823