擴充套件KMP演算法小記

2022-06-26 03:51:13 字數 2489 閱讀 8583

參考來自《拓展kmp演算法總結》:

擴充套件kmp解決的問題:

定義母串s和子串t,s的長度為n,t的長度為m;

求  字串t  與  字串s的每乙個字尾  的最長公共字首;

也就是說,設有extend陣列:extend[i]表示t與s[i,n-1]的最長公共字首,要求出所有extend[i](0<=i(注意到,如果存在若干個extend[i]=m,則表示t在s中完全出現,且是在位置i出現,這就是標準的kmp問題,所以一般將它稱為擴充套件kmp演算法。)

下面舉乙個例子,s=」aaaabaa」,t=」aaaaa」;

首先,計算extend[0]時,需要進行5次匹配,直到發生失配:

從而得知extend[0]=4;

下面計算extend[1],在計算extend[1]時,是否還需要像計算extend[0]時從頭開始匹配呢?

答案是否定的,因為通過計算extend[0]=4,從而可以得出s[0,3]=t[0,3],進一步可以得到 s[1,3]=t[1,3];

計算extend[1]時,事實上是從s[1]開始匹配;

設有輔助陣列next[i]表示t[i,m-1]和t的最長公共字首長度,

在這個例子中,next[1]=4,即t[0,3] = t[1,4],進一步得到t[1,3]=t[0,2],所以s[1,3]=t[0,2],所以在計算extend[1]時,通過extend[0]的計算,已經知道s[1,3]=t[0,2];

所以前面3個字元已經不需要匹配,直接匹配s[4]和t[3]即可,這時一次就發生失配,所以extend[1]=3.

1. 拓展kmp演算法一般步驟

通過上面的例子,事實上已經體現了拓展kmp演算法的思想,下面來描述拓展kmp演算法的一般步驟。

首先我們從左到右依次計算extend陣列,在某一時刻,設extend[0...k]已經計算完畢,並且之前匹配過程中所達到的最遠位置為p,所謂最遠位置,嚴格來說就是i+extend[i]-1的最大值(0<=i<=k);

設取到這個最大值的位置為po,如在上面的例子中,計算extend[1]時,p=3,po=0.

現在要計算extend[k+1],根據extend陣列的定義,可以推斷出s[po,p]=t[0,p-po],從而得到 s[k+1,p]=t[k-po+1,p-po],令len=next[k-po+1](next[i]表示t[i,m-1]和t的最長公共字首長度);

分以下兩種情況討論:

第一種情況:k+len如下圖所示:

上圖中,s[k+1,k+len]=t[0,len-1],

然後s[k+len+1]一定不等於t[len],因為如果它們相等,則有s[k+1,k+len+1]=t[k+po+1,k+po+len+1]=t[0,len],那麼next[k+po+1]=len+1,這和next陣列的定義不符;

所以在這種情況下,不用進行任何匹配,就知道extend[k+1] = len.

乙個例子的模擬:

第二種情況: k+len>=p

如下圖:

上圖中,s[p+1]之後的字元都是未知的,也就是還未進行過匹配的字串,所以在這種情況下,就要從s[p+1]和t[p-k+1]開始一一匹配,直到發生失配為止,當匹配完成後,如果得到的extend[k+1]+(k+1)大於p則要更新未知p和po.

另乙個例子的模擬:

至此,拓展kmp演算法的過程已經描述完成,細心地讀者可能會發現,next陣列是如何計算還沒有進行說明;

事實上,計算next陣列的過程和計算extend[i]的過程完全一樣,將它看成是以t為母串,t為子串的特殊的拓展kmp演算法匹配就可以了;

計算過程中的所需要的next陣列值全是已經計算過的,所以按照上述介紹的演算法計算next陣列不會出現問題,不再贅述。

**模板:

const

int max=100010; //

字串長度最大值

intnext[max],extend[max];

//預處理計算next陣列

void getnext(char

str)

}}//

計算extend陣列

void exkmp(char s1,char

s2) }

}

KMP演算法小記

前段時間寫的有些倉促,有些錯誤,這次修改了以下,並新增了一些適當的注釋,理解起來要容易一些 演算法描述 主串s和模式串t在匹配過程中如果出現不匹配的情況,不需要改變主串的索引i,只需將模式串向右滑動,改變模式串索引j,然後繼續比較s i 和t j 直到完全匹配或者不匹配 即主串遍歷結束時,模式串仍未...

擴充套件KMP演算法

擴充套件kmp 求出a i.lena 1 與b的最長公共字首長度,記為ex i 或者說,ex i 為滿足a i.i z 1 b 0.z 1 的最大的z值 擴充套件kmp可以用來解決很多字串問題,如求乙個字串的最長回文子串和最長重複子串。演算法 設next i 為滿足b i.i z 1 b 0.z 1...

擴充套件KMP演算法

摘自 問題定義 給定兩個字串s和t 長度分別為n和m 下標從0開始,定義extend i 等於s i s n 1 與t的最長相同字首的長度,求出所有的extend i 舉個例子,看下表 i0 1234 567s aaaa abbb taaa aacextend i 54 3210 00為什麼說這是k...