KMP演算法詳解及模板

2021-10-02 05:59:18 字數 1186 閱讀 5582

kmp 演算法是用來解決單模匹配問題的一種演算法。

如果暴力的進行單模匹配,那麼時間複雜度為o(nm)。

kmp 演算法通過對模式串的預處理優化了複雜度。

為了敘述方便,設模式串長度為n,主串長度為m。

將模式串稱為s1,主串稱為s2,下標從1 開始。

我們首先對模式串預處理出乙個next 陣列。

next[i] 表示最大的x,滿足s1[1 : x - 1] 是s1[1 : i - 1] 的字尾。

這個陣列記錄了失配時,模式串指標移動的目標位置。

求next[i] 時,考慮維護乙個位置j,初始時為next[i - 1]。

如果s1[j] = s1[i -1],那麼next[i] 顯然等於j + 1。

如果s1[j] != s1[i - 1],那麼此時需要將j 向前移動到next[j] 的位置。

一直將j 移動到next[j] 的位置,直到j = 0 或s1[j] = s1[i - 1]。

此時next[i] 等於j + 1。

由於next 是最長公共前字尾,因此在j 的移動過程中一定會經過next[i] - 1 的位置。

void getnx()

{ nx[0]=-1;

for(int i=0,j=-1;i在匹配過程中,設在主串中匹配到位置i,模式串中匹配到位置j。

首先如果s2[i] = s1[j],當前位置匹配成功,此時可以把i 和j 同時移動到下乙個位置。

否則發生失配,需要進行調整,我們將j 置為next[j],然後繼續匹配。

同樣由於next 是最長公共前字尾,因此在j 的移動過程中不會跳過可能匹配的位置。

並且模式串中j 之前的部分一定可以匹配。

void kmp()

{ ll i=0,j=0;

while(i可以發現兩部分**有很大相似之處。

其實可以把求next 陣列過程看做用模式串與自身匹配的過程。

在求next 的過程中,j 指標每向後移動一步,i 指標就會向後移動一步。

而j 指標每延next 移動一次,就會向前移動大於等於一步。

由於i 指標會向後移動o(n) 次,因此j 指標也只會向後移動o(n) 次,因此向前同樣最多移動o(n) 次。

因此求next 陣列部分複雜度為o(n)。

與之類似,可以得出匹配過程的複雜度為o(m)。

因此kmp 演算法的總複雜度為o(n + m)。

KMP詳細解釋及KMP演算法模板

kmp是什麼,kmp解決什麼型別的問題 kmp全稱為knuth morris pratt演算法,是一種高效的字串匹配演算法,尋找乙個字串中是否包含另乙個字串,例如 char s ababababcab char p ababc s為模板串 主串 p為子串,在s中找到p的位置 暴力匹配演算法 o n ...

KMP演算法模板及各種應用

給定乙個字串,問最多是多少個相同子串不重疊連線構成。kmp的next陣列應用。這裡主要是如何判斷是否有這樣的子串,和子串的個數。若為abababa,顯然除其本身外,沒有子串滿足條件。而分析其next陣列,next 7 5,next 5 3,next 3 1,即str 2.7 可由ba子串連線構成,那...

KMP演算法(模板)

time limit 1000ms memory limit 65536k 有疑問?點這裡 給定兩個字串string1和string2,判斷string2是否為string1的子串。輸入包含多組資料,每組測試資料報含兩行,第一行代表string1 長度小於1000000 第二行代表string2 長...