拓展KMP演算法

2021-09-27 09:49:24 字數 2046 閱讀 6884

問題模型:

給定字串s和子串t,s的長度為n,t的長度為m;求字串t與字串s的每乙個字尾d的最長公共字首。

拓展kmp演算法

假設 extend 陣列: extend[i] 表示 t 與 s[i, n] 的最長公共字首,目的是求出所有的 extend[0~n-1]。

(注意到,如果存在extend[i] = m,則說明 t 在 s 中完全出現過,那麼問題就變成標準kmp演算法了。)

我們下面的目標就是如何在較短的時間內更新extend陣列;與kmp演算法類似,我們通過利用next陣列來阻止指標的回退。

下面先通過一般的例子來看我們是如何更新extend陣列的:

s = 「aaaabaa」 , t = 「aaaaa」。

顯然extend[0] = 4,顯然當匹配到第5個時失配,共匹配了5次。

我們考慮利用已知的資訊來計算extend[1],已知s[1 , 3] = t[1 , 3],現在要用s[1 , n-1]和t[0 , n-1]進行匹配,如果我們設 nex[1] 存放 t[1 , n-1] 與 t[0 , n-1] 的最長公共字首,nex[1] = 4,這就說明對於s[1, n-1],t[1 , n-1]能匹配上的字元,t[0,n-1]的前nex[1]個也能匹配的上,由於t[1,n-1]只能匹配s[1 , 3]共3個字元,那麼顯然前 3 個字元都可以成功匹配,我們直接匹配下一位即可;於是extend[1] = 3。

演算法步驟

定義extend陣列:extend[i] 表示字串 t 與字串 s[i , n] 的最長公共字首長度。

定義nex陣列:nex[i] 表示 t[i , n] 與 t[1 , n] 的最長公共字首的長度。

首先我們從左到右計算extend陣列,假設在某一時刻 extend[0 , k] 已經計算完畢,並且之前匹配過程中所達到的最遠距離為p,所謂最遠距離即 p = max 的最大值,p』 為達到最遠距離時的 i 。

現在來利用已知的資訊求extend[k+1]:

已知s[p』 , p] = t[0, p-p』],即s[k+1 , p] = t[k+1 - p』 , p-p』]。

設 len = nex[k+1 - p』] ,即 len 為 t[k+1 - p』 , n-1] 與 t[0 , n-1]的最長公共字首。

[外鏈轉存失敗(img-8vyqzv6a-1569379880752)(en-resource://database/2692:1)]

(圖1:當k+lendyx心心 的部落格)

[外鏈轉存失敗(img-ym6jvoew-1569379880755)(en-resource://database/2694:1)]

(圖2:當k+len >= p時情形,其中po = p』,來自 dyx心心 的部落格)

對於nex陣列,其求法和extend陣列類似,詳情參考**中getnex()函式實現方法。

例題模板

洛谷p5410拓展kmp模板

題意簡述:

給定字串s和t,輸出next陣列以及extend陣列。

**示例:

#include

#include

const

int n =

1e6+10;

int nex[n]

;//nex[i] = t[i,n-1]與t[0,n-1]最長公共字首

char s[n]

,t[n]

;//s為目標串,t為模式串

int extend[n]

;void

getnex

(char

* str)}}

void

exkmp

(char

* str1,

char

*str2)}}

void

solve()

intmain()

參考資料

拓展kmp演算法總結

演算法總結第二彈,上次總結了下kmp,這次就來拓展kmp吧。拓展kmp是對kmp演算法的擴充套件,它解決如下問題 定義母串s,和字串t,設s的長度為n,t的長度為m,求t與s的每乙個字尾的最長公共字首,也就是說,設extend陣列,extend i 表示t與s i,n 1 的最長公共字首,要求出所有...

2019 8 6 拓展kmp演算法

首先感謝2014年一位博主寫的部落格 kmp 寫的很詳細 不過有一點小小的錯誤 我就在此基礎上用圖來表示 我把大家視為啥都不懂的小白 現在我們有乙個字串a 我們有一天突然想要知道對於a的每一位開始 最多能和多長的a的字首完全相等?比如我們可愛的ywwyww字串 就是這樣的乙個陣列 6 0 0 3 0...

拓展kmp演算法總結

演算法總結第二彈,上次總結了下kmp,這次就來拓展kmp吧。拓展kmp是對kmp演算法的擴充套件,它解決如下問題 定義母串s,和字串t,設s的長度為n,t的長度為m,求t與s的每乙個字尾的最長公共字首,也就是說,設extend陣列,extend i 表示t與s i,n 1 的最長公共字首,要求出所有...