rabin-karp演算法是由m.o.rabin和r.a.karp發明的一種基於雜湊的字串查詢演算法。
rabin_karp演算法的思想是通過將字串的比較轉回成數字的比較。比較兩個長度為m的字串是否相等需要o(m)時間,而比較兩個數字是否相等通常可以是o(1)。為了將字串對映稱對應的數字,需要用到雜湊函式。
這裡存在乙個問題就是利用雜湊函式將字串對映成對應的數字有可能發生雜湊衝突,也就是說兩個字串通過雜湊函式得到數字相等,但是這兩個字元不同。rabin-karp的解決方法是,如果兩個字串通過雜湊函式得到的數字相等,還需要將這兩個字元利用樸素的方法進行比較。但是如果兩個字串雜湊值不同,那麼這兩個字串一定不同,這就降低比較的時間。
如果雜湊值衝突很少,那麼該演算法的時間複雜度效果很好,最壞的情況就是每乙個雜湊值都衝突,那麼這種情況演算法的複雜度跟樸素演算法相同,算上計算雜湊值的開銷,時間複雜度還要高於樸素演算法。平均情況下,rabin-karp演算法的時間複雜度為o(n+m).
rabin-karp 字串編碼的本質是對字串進行雜湊,將字串之間的比較轉化為編碼之間的比較。在向右滑動視窗的過程中能夠以o(1)的時間複雜度計算出下一位置的雜湊值。另乙個需要解決的問題是整數溢位的問題,rabin-karp是通過除餘運算來解決的。
**如下:
"""
rabin karp演算法
t = (t-text[start-1]*al + text[start+m-1])%modulus
"""class
rabinkarp
:def
__init__
(self)
:# d是輸入字串中的字元數
self.d =
256# 取餘素數
self.modulus =
101 self.success =
false
defsearch
(self, pat, text)
:print
("pat:"
, pat)
print
("text:"
, text)
m, n =
len(pat)
,len
(text)
h =0 t =
0for i in
range
(m):
h =(h * self.d +
ord(pat[i]))
% self.modulus
t =(t * self.d +
ord(text[i]))
% self.modulus
al =
1for i in
range
(m-1):
al =
(al*self.d)
%self.modulus
for start in
range
(n - m +1)
:if t == h:
# 編碼相同還要按個字元進行比較
k =0for i in
range
(m):
if text[start + i]
!= pat[i]
:break
else
:k+=
1if k == m:
print
("匹配成功,"
+"pat在text中的位置是:"
,[start, start + m]
) self.success =
true
if start < n-m:
t =((t -
ord(text[start]
)* al)
*self.d +
ord(text[start + m]))
% self.modulus
while t <0:
t += self.modulus
ifnot self.success:
print
("匹配失敗:text中不存在pat"
)
class
kmp:
defget_pnext
(self,txt)
:"""
生成針對txt中各位置i的下一檢查位置表,用於kmp演算法
"""i, k , m =0,
-1,len
(txt)
pnext =[-
1]*m while iif k==-1
or txt[i]
==txt[k]
: i +=
1 k +=
1if txt[i]
==txt[k]
: pnext[i]
=pnext[k]
else
: pnext[i]
=k
else
: k = pnext[k]
return pnext
defmatching_kmp
(self, t, p, pnext)
: j, i =0,
0 n, m =
len(t)
,len
(p)while j < n and i < m:
if i ==-1
or t[j]
== p[i]
: j, i = j+
1, i+
1else
: i = pnext[i]
if i == m:
return j-i
return
-1
演算法之 字串匹配演算法
一說到兩個字串匹配,我們很自然就會想到用兩層迴圈來匹配,用這種方式就可以實現乙個字串是否包含另乙個字串了,這種演算法我們稱為 bf演算法。bf演算法,即暴力 brute force 演算法,是普通的模式匹配演算法,bf演算法的思想就是將目標串 s 的第乙個字元與模式串 t 的第乙個字元進行匹配,若相...
字串匹配演算法 字串匹配演算法總覽
字串匹配在文字處理裡非常重要,我們採用簡潔的python 把以下演算法一一實現並講解。樸素演算法 algorithm rabin karp 演算法 有限自動機演算法 finite automation knuth morris pratt 演算法 kmp algorithm boyer moore ...
字串匹配演算法之BF vs KMP
最笨的方法bf,暴力匹配,無需多說,最難理解的是kmp演算法,費了好大勁才弄明白。要理解kmp演算法,其實最關鍵的是生成標明下次匹配位置的next陣列。其意義是,如果當前匹配到模式字串的第j個字元是失配,則只需要將j重置為next j 後,繼續向後匹配即可。next j 的值表示p 0.j 1 中最...