kmp求最小迴圈節

2021-08-07 05:48:49 字數 2123 閱讀 8278

kmp最小迴圈節、迴圈週期:

定理:假設s的長度為len,則s存在最小迴圈節,迴圈節的長度l為len-next[len],子串為s[0…len-next[len]-1]。

(1)如果len可以被len - next[len]整除,則表明字串s可以完全由迴圈節迴圈組成,迴圈週期t=len/l。

(2)如果不能,說明還需要再新增幾個字母才能補全。需要補的個數是迴圈個數l-len%l=l-(len-l)%l=l-next[len]%l,l=len-next[len]。

理解該定理,首先要理解next陣列的含義:next[i]表示前面長度為i的子串中,字首和字尾相等的最大長度。

如:abcdabc

index01

2345

67charab

cdab

cnext-10

0001

23如對於a,ab,abc,abcd,很明顯,字首和字尾相同的長度為0

對於長度為5的子串abcda,字首的a和字尾的a相同,長度為1

對於長度為6的子串abcdab,字首的ab和字尾的ab相同,長度為2

接下來舉幾個例子來說明最小迴圈節和迴圈週期:

為方便說明,先設字串的長度為len,迴圈子串的長度為l

1.s0s1s2s3s4s5 ,next[6]=3

即s0s1s2=s3s4s5

很明顯可知:迴圈子串為s0s1s2,l=len-next[6]=3,且能被len整除。

2.s0s1s2s3s4s5s6s7 ,next[8]=6

此時len-next[8]=2 ,即l=2

由s0s1s2s3s4s5=s2s3s4s5s6s7

可知s0s1=s2s3,s2s3=s4s5,s4s5=s6s7

顯然s0s1為迴圈子串

3.s0s1s2s3s4s5s6 ,next[7]=4

此時len-next[7]=3,即l=3

由s0s1s2s3=s3s4s5s6

可知s0s1=s3s4,s2s3=s5s6

從而可知s0s1s2=s3s4s5,s0=s3=s6

即如果再新增3-4%3=2個字母(s1s2),那麼得到的字串就可以由s0s1s2迴圈3次組成

這個定理可以這麼理解:

對於乙個字串,如abcd abcd abcd,由長度為4的字串abcd重複3次得到,那麼必然有原字串的前八位等於後八位。

也就是說,對於某個字串s,長度為len,由長度為l的字串s重複r次得到,當r≥2時必然有s[0..len-l-1]=s[l..len-1],字串下標從0開始

那麼對於kmp演算法來說,就有next[len]=len-l。此時l肯定已經是最小的了(因為next的值是字首和字尾相等的最大長度,即len-l是最大的,那麼在len已經確定的情況下,l是最小的)。

如果一定仔細證明的話,請看下面:

(參考來自:有所改動)

由上,next【i】=j,兩段紅色的字串相等(兩個字串完全相等),s[k....j]==s[m....i]

設s[x...j]=s[j....i](xj=ji)

則可得,以下簡寫字串表達方式

kj=kx+xj;

mi=mj+ji;

因為xj=ji,所以kx=mj,如下圖所示

設s[a…x]=s[x..j](ax=xj)

又由xj=ji,可知ax=xj=ji

即s[a…i]是由s[a…x]迴圈3次得來的。

而且看到沒,此時又重複上述的模型,s[k…x]=s[m…j],可以一直遞推下去

最後可以就可以遞推出文章開頭所說的定理了。

最後再舉兩個相關例子

abdabdab  len:8 next[8]:5

最小迴圈節長度:3(即abd)   需要補的個數是1  d

ababa  len:5 next[5]:3

最小迴圈節長度:2(即ab)    需要補的個數是1  b

kmp求最小迴圈節

kmp最小迴圈節 迴圈週期 定理 假設s的長度為len,則s存在最小迴圈節,迴圈節的長度l為len next len 子串為s 0 len next len 1 1 如果len可以被len next len 整除,則表明字串s可以完全由迴圈節迴圈組成。迴圈週期t len l。2 如果不能,說明還需要...

KMP求最小迴圈節講解

kmp最小迴圈節 迴圈週期 定理 假設s的長度為len,則s存在最小迴圈節,迴圈節的長度l為len next len 子串為s 0 len next len 1 1 如果len可以被len next len 整除,則表明字串s可以完全由迴圈節迴圈組成,迴圈週期t len l。2 如果不能,說明還需要...

最小迴圈節

分類 資料結構 2013 04 05 20 01 157人閱讀收藏 舉報 acm演算法 資料結構 kmp最小迴圈節 通過kmp中的 next 陣列求最小迴圈節 題目要求 給出乙個字串,求出將字串的全部字元最少迴圈2次需要新增的字元數。cpp view plain copy print?include...