重複字串的判定問題(kmp 演算法)

2021-08-05 22:15:28 字數 1553 閱讀 5733

該篇文章給出另一種解法,基於 kmp 演算法的判定。

該演算法是舉例發現的,

設迴圈單元長度為 l, 設 len = l*n

則 [0,l) = [l, 2*l) = [2*i ,3*l ) = [3*l, 4*l) = [4*l, 5*l) = ...... = [(n-1)*l, n*l)

那麼,原串必然存在前字尾相等。因而可以聯想到 kmp 演算法的 next 陣列(在作者認知,稱為t1length 陣列),

給出乙個觀察後的結論,如果前字尾匹配的長度是不匹配長度的整數倍(含 1)則串是重複的

構思這個解決方法時,掉過乙個坑,認為只要匹配的長度大於不匹配的長度即可。舉反例可以推翻這個設想:

abcabca,前字尾匹配的長度為 4,而不匹配的長度為 3,4 > 3 但是它明顯不是乙個重複結構。

下面證明命題:如果前字尾匹配的長度是不匹配長度的整數倍(含 1)則串是重複的

設對長為 strlen 的串計算 kmp 演算法的 t1 陣列的最後乙個元素值 m 表示整個串前字尾匹配長度為 m,

觀察整個串,若匹配的長度 m 比不匹配的長度 notc 更長,則說明它必然是乙個重複的

且 m 一定是 notc 的整數倍.

這是充分必要的. 

1.假設長度為 len 的串是重複的,最小單元是 notc,則 m(len-notc)

即是 t1 陣列的最後乙個元素值。且 m 一定是 notc 的整數倍。

2.假設 m 是串 str 的 t1 陣列最後元素的值,且 m 是 notc 的整數倍,便於理解設

m=3*notc,len=4*notc,則首先有 str[0,3*notc) = str[notc,4*notc),將 

str[0,3*notc) 分為三部分,依次與 str[notc,4*notc) 比較,可知

str[0,notc)=str[notc,2*notc), 

str[notc,2*notc)=str[2*notc,3*notc), 

str[2*notc,3*notc)=str[3*notc,4*notc)

於是有 str[0,notc)=str[notc,2*notc)=str[2*notc,3*notc)=str[3*notc,4*notc)

這也就證明了 str 是乙個重複的字串

當 m=n*notc 時,同樣也可以把 str[0,n*notc) 拆為 n 部分:

str[0,notc), str[notc,2*notc).... , str[(n-1)*notc, n*notc) 依次與

str[notc,(n+1)*notc) 的 n 部分:

str[notc,2*notc).... , str[(n-1)*notc, n*notc)各項比較則可以得出

str[0,notc) = str[notc,2*notc) = ...... = str[(n-1)*notc, n*notc) = str[notc,(n+1)*notc)

因此 str 是乙個重複的字串

原理已經非常簡單,t1 陣列計算的方法也十分明顯。問題已經非常輕鬆地解決了。

**見:

重複字串的判定問題(kmp 演算法之優化版本)

給出了基於 kmp 演算法的字串重複判定思路,但是在使用這個演算法判定乙個長度為 1024 1024 1024 的字串是否重複時 編譯為 32 位程式 記憶體爆掉了,這提示了該演算法很占用記憶體。是的,字串全部載入到記憶體裡面需要乙份記憶體,t1 陣列需要四倍於它的記憶體 int 陣列,長度與串一致...

字串 KMP演算法,重複的子字串

普通的方法,雙指標逐個比較 class solution begin1 begin2 if match return false kmp方法,在乙個串中查詢是否出現過另乙個串,這是kmp的看家本領。如果len len next len 1 0 則說明 陣列長度 最長相等前字尾的長度 正好可以被 陣列...

判定重複字串c語言版(基於kmp

串中任意個連續的字元組成的子串行稱為該串的子串。目標 輸入乙個非空的字串,判斷它是否可以由它的乙個子串重複多次構成。說明 輸入的字串只含有小寫英文本母,並且長度不超過10000。輸出的可以是布林型別的值,也可以是 1 或 0,其中 1 表示可以由它的乙個子串重複多次 構成,0 相反,能表達出意思即可...