KMP演算法 字串匹配

2021-07-30 03:12:06 字數 1602 閱讀 2687

我先要對網上那些所謂「教你從頭到尾徹底理解」、「如果你看不懂**,那就看一看這篇文章」、「絕對原創,絕對通俗易懂」、「如果都說成這樣你都不明白,那麼***」這些言論批判一番。如果你的文章真的寫的好,那還沒什麼,可問題是你的文章在關鍵處出現了錯別字、用一些故作高深的文字、甚至還出現了錯誤,那我也不知道你是有多厲害。標題黨就是fxxk

kmp演算法其實就是一種字串匹配的演算法。具體說來,就是判斷乙個長度是m的模式串(tar)是否是另乙個長度為n的主串(pat)的子串。

我們首先可以思考一下暴力演算法。

直接每一位比較,失配後再從下一位開始繼續比較。o(

n×m)

的時間複雜度。還是比較簡單的。

這樣的複雜度對於稍微大一點的資料規模就過不去了。我們需要一種更高階的演算法。

暴力演算法有沒有可以優化的地方呢?考慮一下:對於乙個位置,如果我們已經匹配了前面的一小段,到中間某處才失配,我們是否有必要從下乙個位置繼續匹配?我們可不可以跳過後面的一些位置,接著從乙個「有意義」的位置開始繼續匹配?

假設模式串的子串[1

,i] 是ab

c∗∗∗

∗abc

(abc代表這個子串的前面後面都是完全一樣的部分,那些*代表中間一些不同的字元),當我們在模式串的i+

1 位置失配時,下一次匹配不用在從模式串的開頭開始比較了,為什麼不從模式串的

4 位置開始比較呢(因為在i+

1位置失配時,最後的那個ab

c 一定已經匹配,而前面的也是ab

c ,不用再次比較)?

這樣就可以大大減少我們的比較次數,模式串的子串[1

,i] 中前面後面相同部分(稱為公共前字尾)的長度記為ne

xt[i

] 。

但是我怎麼知道ne

xt[i

] 的值呢?

我們其實可以遞推計算。

假設對於位置

j ,我們已經知道ne

xt[j

],現在求ne

xt[j

+1] 。

考慮兩種情況:先設k=

next

[j] 。 如果t

ar[k

+1]=

tar[

j+1]

,那麼ne

xt[j

+1]=

next

[j]+

1 ;(顯然)

否則 現在比較顯然的是,ne

xt[j

+1]xt[j

] 。

而且,j+1

的公共前字尾一定也屬於某個公共前字尾(因為除去最後新加入的ta

r[j+

1],前面的某個到j的字尾也有對應的相同的字首)。

所以,一直尋找更小的公共前字尾,直到其字首尾隨的那個字元與ta

r[j+

1]相同。

//計算next

next[0] = 0 ;

for ( i = 2, j = 0 ; i <= m ; i ++ )

利用next匹配:

for ( i = 1 ; i <= n ; i ++ ) 

}

短小而精悍的kmp。

KMP演算法 字串匹配

kmp演算法基本思想 我們在用常規的思想做 字串匹配時候是 如 對如 字元如果 t abab 用p ba 去匹配,常規思路是 看 t 第乙個元素 a 是否 和p 的乙個 b 匹配 匹配的話 檢視各自的第二個元素,不匹配 則將 t 串的 第二個元素開始 和 p 的第乙個匹配,如此 一步一步 的後移 來...

KMP字串匹配演算法

kmp核心思想 計算模式串的next陣列,主串的索引在比較的過程中不回朔 ifndef kmp h define kmp h class kmp endif include kmp.h include include include using namespace std int kmp calcu...

KMP字串匹配演算法

在介紹kmp演算法之前,先介紹一下bf演算法。一.bf演算法 bf演算法是普通的模式匹配演算法,bf演算法的思想就是將目標串s的第乙個字元與模式串p的第乙個字元進行匹配,若相等,則繼續比較s的第二個字元和p的第二個字元 若不相等,則比較s的第二個字元和p的第乙個字元,依次比較下去,直到得出最後的匹配...