用KMP來求字串的迴圈節

2021-06-23 07:48:53 字數 1282 閱讀 7002

利用kmp演算法中的next值可以求出字串的迴圈節,如ababab的迴圈節為ab,abcd的迴圈節為abcd,具體做法如下:假設字串的長度為len,next[len]為字串的最後乙個字元的下乙個字元的next值(下標從0開始),如果len% (len - next[len]) == 0,那麼迴圈節的迴圈次數為len / (len -next[len]),否則為1,為什麼呢?詳細說明如下:

首先,對於給定的長度為len的字串str,根據next的定義可知,str[0~(next[j]-1)] =str[(j-next[j])~(j-1)],且next[j]為滿足該條件的值當中的最大那乙個,令迴圈次數為k,則

當k = 1時,根據next的意義可知next[len] = 0,所以len / (len -next[len]) = 1,結論正確;

當k = 2時,如abcdabcd,如果最後乙個d後面還有字元的話,那麼它的next的值應該指向第二個a,為4,len %(len - next[len])= 8 % (8 - 4) = 0,迴圈次數為2,結論正確;

當k >= 3時,有len = k * (len -next[len])(x >= 3),next[len] = (1 - 1 / k) * len> (1 / 2)len,即next[len]位於字串的中間位置之後,如圖1所示,且黃色部分與藍色部分一樣,

所以,在圖2中,紫色部分跟綠色部分也一樣(假設二者長度一樣),

由於黃色部分跟藍色部分是一樣,且藍色部分結尾的兩段(紫色跟綠色)是一樣的,因而黃色部分在結尾部分也應該有兩段一樣的,即綠色跟它前面相同長度的一段,假設為紅色,此時紅色部分是藍色部分的倒數第三段,且跟前兩段一樣,這也將導致黃色部分也將產生倒數第三段,這樣,藍色部分的倒數第k段永遠是是黃色部分的倒數第k-1段,只要證明藍色跟黃色的公共部分是紫色部分的整數倍,那麼就可以說該公共部分是由n個紫色部分組成,由於藍色部分跟黃色部分長度一樣,二者又有公共部分,所以圖2中紅色部分跟紫色部分長度一樣,又因為整個字串長度是紫色部分的整數倍(>=3),所以公共部分的長度也是紫色部分的整數倍(>= 1),如此一來,公共部分部分是由n個紫色部分組成(n>=1),從而紅色部分跟紫色部分也必然一樣(紅色部分是黃色部分的跟紫色長度相同的第一部分),所以,整個字串是由n個紫色部分組成的(n>= 3),結論正確。

綜上所述,結論的充分性得證,另外,由next的意義可以很容易證明必要性。

KMP演算法求字串的最小迴圈節

說到求字串的最小迴圈節就不得不提及kmp演算法 因為要求迴圈節,還需要用到kmp演算法的next陣列 kmp演算法本來是用來求乙個串中是否包含另乙個串,或者說乙個串是否為另乙個串的子串 kmp演算法詳解,看不懂算我輸 如果kmp演算法理解其原理了,那麼這道題也是非常簡單的 用了kmp中的next陣列...

HDU3746 (KMP)字串最小迴圈節問題

傳送門 題意 給你乙個串,要你在串頭或尾新增最少的字元,使得該串至少有2個迴圈節,問你最少需要加幾個字元.如 aaa 迴圈為 a 已有3個迴圈節 abca 迴圈節為abc 至少在末尾加 bc 使得該串至少有2個迴圈節 abcde 迴圈節為abcde 至少在末尾加 abcde 使得該串至少有2個迴圈節...

hdu1010 擴充套件KMP求字串最小迴圈節

problem 擴充套件kmp求字串最小迴圈節 analyse 字串迴圈節等於字串最長字首字尾減去這個字首字尾中間交的長度。jibancanyang author jibancanyang created time 六 5 7 21 17 06 2016 file name hdu1010.cpp ...