查找字符串之boyer-moore算法

1 問題的提出

給出字符串P和T,長度分別爲n和m。找出P在T中出現的所有位置。

2 原始匹配算法

int Index(char* P,char* T,int pos)
{
	i = pos; j = 0;
	while( i<=strlen(T) && j<=strlen(P) ){
		if(P[j] == T[i])  {++i;  ++j;}
		else  {i -= j;  j = 0;}
}
if(j> strlen(P))  return (i – strlen(P) + 1);
else    	      return -1;
}
    上述算法的最壞時間複雜度爲O(mn)。boyer-moore算法、KMP算法、suffix tree算法(後綴樹)能夠在線性時間內處理的字符串的匹配問題。
    suffix tree算法需要對字符串T進行預處理,而boyer-moore算法和KMP算法需要對P進行預處理。所以,suffix tree比較適合T不變,P變化的場景。boyer-moore算法和KMP算法適合T變化,P不變的場景。本文即是對boyer-moore算法的理論性介紹。

3 字符串匹配算法之boyer-moore算法

3.1 從右到左掃描

    在進行一次的匹配過程中,掃描P是從右向左的。如下圖,在第一次的匹配過程中,首先比較P[7]和T[7],然後比較P[6]和T[6],從右向左滑動。


3.2 壞字符規則

    見圖2。第一次比較:T[7](=x) ≠ P[7](=a),結果是不匹配,此時如果我們知道x在P中出現的right-most位置爲4,就可以移動P至圖3中所示的位置。


定義:
字符集中的任一字符x,R(x)表示在P中出現的right-most位置,如果x沒有在P中出現,則R(x)置爲0。計算R(x)的時間複雜度爲O(n)。


壞字符規則:
在某次匹配過程中,P的最右邊的 n-i 個字符已經和T中的匹配,但是第i個字符不匹配(對於T中的第k個字符),此時P應該向右移動 max( 1, i – R(T[k]) )。


壞字符規則在實際應用中特別高效。但是如果字符集比較小,則效率較差,時間複雜度達不到線型。

3.3 好後綴規則

好後綴規則:
    在某次的匹配過程中,P的一個後綴匹配了T中的的子串t,但是子串t左邊的第一個字符不匹配,如果P中存在滿足如下條件的子串t`:
1 t`=t,但t`不是P的後綴
2 在P中位於t`左邊的第一個字符 ≠ 在P中位於t左邊的第一個字符
3 在滿足第1,2條件下,在P中位置處於最右的t`
    則移動P使得t` 與T中的t對齊,如圖5所示。如果不存在,則向右移動P最少距離,使得P的某個前綴匹配T中的t的某個後綴,如圖6。如果還沒有匹配的,則P向右移動n個位置,如圖7。


【定義】
對於任一i∈(1,n),L(i) 是滿足下列條件的值:
1 L(i) < n
2 字符串P[i…n] 匹配P[1…L(i)]的後綴
3 如果存在滿足條件1和2的情況,則取最大值 ,否則取值爲0

【定義】
Nj(P)是 滿足如下字符串的長度:
1 是P[1…j]的後綴
2 是P的後綴
3 滿足條件1,2的最長字符串

【定理】
L(i) 是 滿足條件Nj(P) = |P[i…n]|= n–i +1 的j的最大值。
根據如上定理,計算L(i)的算法如下:

for i:=1 to n do L(i) := 0;
for j:=1 to n-1 do
	begin
	i:=n - Nj(P) + 1;
	L(i) = j;
	end;

3.4 完整的boyer-moore算法

    在3.2和3.3節中,給出了2個移動的位置。在boyer-moore算法中,取2個值中的最大值。

3.5 複雜度分析

    在壞字符規則中,計算R(x)的時間複雜度爲O(n);在好後綴規則中,計算L(i)的時間複雜度爲O(n)。所以boyer-moore算法的時間複雜度爲O(m+n)。

4 KMP算法

    假設主串爲s1 s2 …sn 模式串爲p1 p2…pm 。當匹配過程中產生失配(即si≠pj)時,模式串向右滑行多遠,換句話說,當主串第i個字符與模式串中的第j個字符發生失配時,主串中的第i個字符(i指針不回溯)應用與模式中的哪個字符比較?
next[j] = 0  當j=1
     = Max{k| 1<k<j 且 p1…pk = pj-j+1…pj-1 }
=1 其它情況
    複雜度分析。計算next數組的複雜度爲O(m),所以最終匹配的複雜度爲O(m+n)。
發佈了28 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章