求字符串的每个前缀的大于等于2的循环节长度,考察对KMP中next数组的理解
结论是:令j=i-next[i],如果i%j==0且i/j>1,j就是Pi的最小循环节(Pi表示文本串的前i个字符)
即要证明,当i%j==0且i/j>1时,j是Pi的最小循环节长度
显然,当i%j!=0时,j不可能是循环节的长度,更不用说是最小循环节长度,那么,在i%j==0的范围内
i/j=1时,忽略
i/j=2时,由next数组的定义可知P[1,j]=P[j+1,i],由于next数组最大化的定义,此时j必然是最小的循环节
由数学归纳法,设i/j=k(k>=2),且i%j==0,j是Pi的最小循环节长度,则i'=i+j,j'=i'-next[i']时,若j'=j,那么i'%j==0,j也是Pi‘的最小循环节长度
如果P[i+1,i']与P[1,j]不相同,那么j不会是Pi'的最小循环节,因为j是Pi的最小循环节,而P[i+1,i']与循环节不同
否则,P[i+1,i']与循环节相同,Pi由P[1,j]循环i/j次组成,Pi'由P[1,j]循环i/j+1次组成
而且,由于next数组最大化的定义,这一定是个最小的循环节,否则P[i+1,i']与P[1,j]不相同,next[i']<next[i]+j,即j'=i'-next[i']>j,j’可能会是一个更长的循环节
代码: