對於給定的字串strings和sub_s,判斷strings中是否包含sub_s,並返回出現位置,暴力演算法匹配字串過程:把strings [0] 跟sub_s [0] 匹配,如果相同則匹配下乙個字元,出現不匹配的字元時我們會丟棄前面的匹配資訊,然後把strings [1] 跟sub_s [1] 匹配,迴圈進行,直到主串結束,或者匹配成功。這種匹配演算法極大地降低了匹配效率,時間複雜度是o(nm)。
kmp演算法較之暴力匹配演算法引進了乙個部分匹配表,從該表中可以得到向後移動位數。下面舉例說明:
stringsb
abcb
abca
bcaa
bcab
cabc
acab
sub_sa
bcab
caca
b 1.首先將strings和sub_s的第乙個字元進行比較,如果不匹配,向後移動一位5
stringsba
bcb
abca
bcaa
bcab
cabc
acab
sub_sab
ca b
caca
b 2.此時a與a匹配,接著比較字串的後幾位,發現第5位出現不匹配現象,這時最自然的反映是,將sub_s向後移動一位(如下圖所示),然後從sub_s[0]與strings[3]開始逐個比較,你會發現已經比較過的位置需要再次作比較,這樣做極大的降低了效率。
stringsba
bcba
bcab
caab
cabc
abca
cabsub_sab
cabc
acab
3.當第5位出現b和a不匹配時,我們知道字串前三位 「abc」,根據這個資訊可以算出sub_s向後移動的位數,這樣對於已經比較過的位置無需重複比較,從而提高匹配效率。移動位數=已匹配的字元數-對應的部分匹配值。
4.對於此例中的strings和sub_s的匹配其對應的部分匹配表,如下表所示:j1
2345
6789
10sub_[j]ab
cabc
acab
部分匹配值00
0123
1012
5. 當第5位出現b和a不匹配時,前面三個字元「abc」是匹配的,最後乙個匹配字元c對應的匹配值是1,根據
移動位數=已匹配的字元數-對應的部分匹配值,得到移動位數為3(3 - 0 = 3)。5
stringsba
bcb
abca
bcaa
bcab
cabc
acab
sub_sa
bcab
caca
b 6.b與a不匹配,後移一位,逐位比較a與c不匹配,向右移動7位(7-0 =7)13
stringsba
bcba
bcab
caa
bcab
cabc
acab
sub_sab
cabc
ac a
b 7.右移動7位後,b與c不匹配,後移7位(7-0=7),然後逐次比較,直至string最後一位,若發現完全匹配,則匹配成功,否則失敗。這裡不再繼續重複。20
stringsba
bcba
bcab
caab
cabc
ab c
acab
sub_s a
bcab
cac
ab
8.部分匹配值計算
"字首"指除了最後乙個字元以外,乙個字串的全部頭部組合;"字尾"指除了第乙個字元以外,乙個字串的全部尾部組合。部分匹配值"就是"字首"和"字尾"的最長的共有元素的長度。以"abcabcacab"為例
sub_s[j]
字首字尾
共有部分及長度
a[ ]
[ ][ ]:0
ab[a]
[b][ ]:0
abc[a,ab]
[bc,c]
[ ]:0
abca
[a,ab,abc,]
[bca,ca,a]
[a]:1
abcab
[a, ab,abc,abca]
[bcab,cab,ab,b]
[ab ]:2
abcabc
[a,ab,abc,abca,abcab]
[bcabc,cabc,abc,bc,c]
[abc]:3
abcabca
[a,ab,abc,abca,abcab,abcabc,]
[bcabca,cabca,abca,bca,ac,a]
[a]:1
abcabcac
[a,ab,abc,abca,abcab,abcabc,abcabca]
[bcabcac, cabcac, abcac, bcac, cac, ac,c]
[ ]:0
abcabcaca
[a,ab,abc,abca,abcab,abcabc,abcabca,
abcabcac]
[bcabcaca, cabcaca, abcaca, bcaca, caca, aca, ca,a]
[a]:1
abcabcacab
[a,ab,abc,abca,abcab,abcabc,abcabca,
abcabcac,abcabcaca]
[bcabcacab, cabcacab, abcacab, bcacab, cacab, acab, cab, ab,b]
[ab ]:2
KMP演算法原理
字串匹配是最電腦科學的基本研究問題之一,在文件檢索 生物資訊等領域有著舉足輕重的地位。簡單來說字串匹配問題就是 如何確定某字串是否包含另一字串。暴力搜尋演算法 brute force,bf 是最容易想到和實現的,但是它高達o n 2 時間複雜度難以滿足許多場景。kmp演算法是一種改進的字串匹配演算法...
KMP演算法原理解析
這種演算法不太容易理解,網上有很多解釋,但讀起來都很費勁。直到讀到jake boxer的文章,我才真正理解這種演算法。下面,我用自己的語言,試圖寫一篇比較好懂的kmp演算法解釋。首先,字串 bbc abcdab abcdabcdabde 的第乙個字元與搜尋詞 abcdabd 的第乙個字元,進行比較。...
KMP字元匹配演算法原理
掘金位址鏈結 簡介 kmp演算法是一種改進的字元匹配演算法。由d.e.knuth,j.h.morris和v.r.pratt提出的,因此人們稱它為克努特 莫里斯 普拉特操作 簡稱kmp演算法 它的核心思想是,通過乙個next陣列,在匹配失敗後,減少字元移動的距離,達到快速匹配的目的。要想徹底理解kmp...