我先要對網上那些所謂「教你從頭到尾徹底理解」、「如果你看不懂**,那就看一看這篇文章」、「絕對原創,絕對通俗易懂」、「如果都說成這樣你都不明白,那麼***」這些言論批判一番。如果你的文章真的寫的好,那還沒什麼,可問題是你的文章在關鍵處出現了錯別字、用一些故作高深的文字、甚至還出現了錯誤,那我也不知道你是有多厲害。標題黨就是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的第乙個字元,依次比較下去,直到得出最後的匹配...