算法五——字符串匹配(上)
文章內(nèi)容、圖片均來自極客時間。
如何借助哈希算法實現(xiàn)高效字符串匹配
1 概念和用途
字符串匹配:查找一個字符串A在字符串B中是否出現(xiàn),這個過程就是字符串匹配。A稱為模式串,B稱為主串。主串的長度記為n,模式串長度記為m。n>mn>mn>m。
在java中有String的indexOf用就是字符串匹配。
字符串匹配有基礎(chǔ)的BF算法、高效的KMP算法。
2 BF算法
BF=Brute Force 暴力搜索
算法思想:在主串中,分別從起始位置0,1,2…n-m且長度為m的n-m+1個子串是否和模式串相同。
從算法過程分析,最壞時間復(fù)雜度是O(nm)。例如主串是“aaaa…aaa”(省略符號表示有若干個a)。模式串是"aaaab"。因為有n-m+1個子串,每次比較m次。比較總次數(shù)是(n?m+1)?m=n?m?m2+m(n-m+1)*m=n*m-m^2+m(n?m+1)?m=n?m?m2+m,記為O(nm)。
BF盡管時間復(fù)雜度比較高,但在實際應(yīng)用中經(jīng)常使用。原因有二。
第一,在實際應(yīng)用中字符串都比較短,每次兩個字符串比較的時候遇到不相同的字符,就可以提前返回。所以實際比n*m要少。
第二,算法思想簡單,實現(xiàn)簡單,不容易出錯。這也符合KISS(Keep it simple and stupid)原則。在工程中,滿足性能的前提下,簡單是原則。
3 RK算法
RK=Rabin-Karp,是該算法的兩位提出者。
在BF算法中,兩次字符串比較,因為要比較m次,復(fù)雜度較高。如果為每個字符串計算一個哈希值,每次比較哈希值,復(fù)雜度就可能會降低。
算法思想:對模式串求哈希值。對n-m+1個主串中的子串分別求哈希值,然后逐個和模式串的哈希值比較。因為哈希值是一個數(shù)字比較非常快。但是因為求哈希所以整體算法效率沒有提高。
改進(jìn):可以通過改進(jìn)求子串哈希值,降低時間復(fù)雜度。假如字符串中只包含a-z這26個字母,每個字母分別對應(yīng)數(shù)字0~25。哈希值采用26進(jìn)制表示。
例如:"dbc"=d?26?26+b?26+c=3?26?26+1?26+2=2056"dbc" = d*26*26+b*26+c=3*26*26+1*26+2=2056"dbc"=d?26?26+b?26+c=3?26?26+1?26+2=2056
這種哈希方法相鄰子串哈希值是有特點的。可以使用前一個子串的哈希值計算下一個子串的哈希值。
記h1=hash(dbc)=32626+126+2,h2=hash(bce)=12626+226+4.
A=126+2
B=12626+226
那么B=26*A
令h[i-1]表示(i-1,i+m-2)子串的哈希值,h[i]表示(i,i+m-1)子串的哈希值。那么
h[i]=(h[i?1]?26m?1(s[i]?′a′))?26+(s[i+m?1]?′a′)h[i]=(h[i-1]-26^{m-1}(s[i]-'a'))*26+(s[i+m-1]-'a')h[i]=(h[i?1]?26m?1(s[i]?′a′))?26+(s[i+m?1]?′a′)
這里還可以提高的地方時,可以提前把26026^0260,26126^1261,…26m?126^{m-1}26m?1存入數(shù)組中。次方就是數(shù)組下標(biāo),便于查詢。
時間復(fù)雜度分析
計算哈希值主要掃描一遍主串即可,時間復(fù)雜度O(n)。計算子串與模式串哈希值比較是否相同,時間復(fù)雜度O(1),共需要n-m+1次比較, 時間復(fù)雜度O(n)。總體時間復(fù)雜度時間復(fù)雜度O(n)。
字符串很長,哈希值超出能表示的范圍怎么辦?
上面的設(shè)計完全沒有哈希沖突,當(dāng)允許有哈希沖突,會不會解決呢?上面的算法是進(jìn)位相乘,如果改為加法,數(shù)值就小很多了。例如"dbc"=3+1+2=6"dbc"=3+1+2=6"dbc"=3+1+2=6。這樣的話取值范圍小多了,但哈希沖突概率會很高。如果每個字母不對應(yīng)整數(shù),而是對應(yīng)從小到大不同的素數(shù),這樣哈希沖突的概率就會降低了。
如果有哈希沖突了,怎么辦?
當(dāng)兩個字符串哈希值相同的時候,就挨個字符串比較,確保字符串真的相同。只是如果這樣,當(dāng)沖突概率很高的時候,RF比BF的效率還低。因為還要計算哈希。
4 思考題
上面講的是一維字符串的比較,如果是主串和模式串都是一個二維矩陣,怎么匹配呢?
解決思路:可以將二維矩陣轉(zhuǎn)為一個數(shù)組,變成一維的,再比較。
總結(jié)
以上是生活随笔為你收集整理的算法五——字符串匹配(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数据结构与算法】图
- 下一篇: Maven for Eclipse 第二