KMP匹配演算法複習。。

2021-08-07 07:12:58 字數 2287 閱讀 6386

kmp演算法(knuth–morris–pratt algorithm),knuth就是高德納。

kmp演算法是從樸素匹配演算法改進而來:就是窮搜匹配。

樸素匹配演算法:

原串:abcde 模式串:acd

1. 將原串和模式串左對齊,然後一位一位比較,直到有乙個字元不匹配

2. 發現第二位的b和c不匹配,模式串右移一位

3. 重複這個流程,直到找到完全匹配的子串或者匹配失敗。

樸素匹配演算法的不足:

就是不能夠很直觀的進行有移動的大跨步,也就是明明是不匹配的,但是不能跳過去,不夠聰明。

例子:abcdeabcdf 和 abcdf。遇到e和f時候衝突,

此時明顯人能直到應該直接調到e後面的a開始啊。

其實不是這樣的。

原串為abcdabcdabf,模式串為abcdabf,直接跳過相同部分就會遺漏匹配的串,所以跳過的長度並不是前面完全匹配的部分

其實就是人之所以強大是可以馬上發現下乙個匹配開始的位置,比如模式串是a開頭,那麼匹配串肯定每次都是找到原串下乙個a開始的繼續匹配。機器不知道下乙個究竟在哪,怎麼跳過去合適。

也就是機器怎麼靠近人的眼睛呢。直接發現下乙個合理的開始位置呢,也就是如何跳到那個合理位置呢?這就是kmp演算法解決的.

kmp演算法

kmp演算法需要對模式串進行預處理。

把可以跳過的長度一般儲存在模式串的partial match table中。

例如:abcdabf的partial match table如下:

可以跳過的長度 = 當前模式串已匹配長度 - 模式串最後乙個字母在partial match table中的值。例如:

當發現c和f不匹配時,根據公式,當前已匹配串abcdab長度為6, 最後乙個字母b在partial match table中的對應值為2,所以可以跳過的長度 = 6 - 2 = 4,即:

【partial match table是如何構建的?】

每個位置i記錄的其實就是從0到i的子串中,同時出現在子串字首和字尾中的最大長度。還是以上面那個例子為例:

'''

knuth-morris-pratt algorithm

'''def

getprefix

(pattern):

''' @param pattern: pattern string.

@return: prefix array.

'''length = len(pattern)

prefix = [0] * length

for i in range(1, length):

k = prefix[i-1]

while k > 0

and pattern[i] != pattern[k]:

k = prefix[k-1]

if pattern[i] == pattern[k]:

prefix[i] = k + 1

return prefix

defkmp

(src, pattern):

prefix = getprefix(pattern)

print(prefix)

i = j = 0

src_len = len(src)

pattern_len = len(pattern)

if src_len < pattern_len:

return -1

while i < src_len:

while src[i] == pattern[j]:

if j == pattern_len - 1:

return i - j

else:

i += 1

j += 1

if j > 0:

j = prefix[j-1]

else:

i += 1

return -1

src = 'bbc abcdab abcdabcdabde'

pattern = input('pattern: ')#'abcdabd'

#print(kmp(src, pattern))

print(getprefix(pattern))

【延展】

這類問題的思路是解決重複,有點像qucik sort消除逆序對。

複習 KMP演算法

對於kmp演算法的學習,在寒假時我還是搞不太明白,但幾個月之後,對於它的理解又更近了一步。首先是對於子串的自我匹配,求乙個fail陣列,fail i 對於字串ss的前ii個字元構成的子串,既是它的字尾又是它的字首的字串中 包括他 最長的長度記作fail i 舉個例子,abcdabc中fail 7 的...

KMP匹配演算法

1.概述 在講解kmp匹配演算法之前,我們不妨來看看我們用暴力法是怎麼完成字串的匹配的.在我們的目標串t 101011011,和模式串p 110中,我們在t中找尋p第一次出現在t中的下標.通過上圖,我們發現我們利用暴力匹配法,在某次失敗後我們只能非常機械的一步一步移動我們的模式串p.所以我們理解了上...

演算法 kmp匹配演算法

執行結果 心得收穫 完整 計算next陣列 next陣列的目標是求得從開始到當前位置的字串相同最大前字尾長度為多少 該值的作用是在當前位置的字元匹配失敗時,匹配字串應該從那裡開始繼續匹配,而不用回到開頭 時間複雜的 o m void calnextarray const string str,int...