資料結構與演算法 字串匹配 BM演算法

2021-10-23 19:26:00 字數 2807 閱讀 9118

單模式串匹配

bf 演算法和 rk 演算法

bm 演算法和 kmp 演算法

多模式串匹配演算法

trie 樹和 ac 自動機

bm演算法的核心思想是通過將模式串沿著主串大踏步的向後滑動,從而大大減少比較次數,降低時間複雜度。而演算法的關鍵在於如何兼顧步子邁得足夠大與無遺漏,同時要盡量提高執行效率。這就需要模式串在向後滑動時,遵守壞字元規則與好字尾規則,同時採用一些技巧。

壞字元規則

從後往前逐位比較模式串與主串的字元,當找到不匹配的壞字元時,記錄模式串的下標值si,並找到壞字元在模式串中,位於下標si前的最近位置xi(若無則記為-1),si-xi即為向後滑動距離。(但是壞字元規則向後滑動的步幅還不夠大,於是需要好字尾規則。

好字尾規則

從後往前逐位比較模式串與主串的字元,當出現壞字元時停止。若存在已匹配成功的子串{u},那麼在模式串的{u}前面找到最近的{u},記作{u』}。再將模式串後移,使得模式串的{u』}與主串的{u}重疊。若不存在{u』},則直接把模式串移到主串的{u}後面。為了沒有遺漏,需要找到最長的、能夠跟模式串的字首子串匹配的,好字尾的字尾子串(同時也是模式串的字尾子串)。然後把模式串向右移到其左邊界,與這個好字尾的字尾子串在主串中的左邊界對齊。

首先在每次匹配過程中,一旦發現壞字元,先執行壞字元規則,如果發現存在好字尾,還要執行好字尾規則,並從兩者中選擇後移距離最大的方案執行。

技巧:1.通過雜湊表實現,壞字元在模式串中下標位置的快速查詢。

// 全域性變數或成員變數

private

void

generatebc

(char

b,int m,

int[

] bc)

for(

int i =

0; i < m;

++i)

}public

intbm

(char

a,int n,

char

b,int m)

if(j <0)

// 這裡等同於將模式串往後滑動j-bc[(int)a[i+j]]位

i = i +

(j - bc[

(int

)a[i+j]])

;}return-1

;}2.每次執行好字尾原則時,都會計算多次能夠與模式串字首子串相匹配的好字尾的最長字尾子串。為了提高效率,可以預先計算模式串的所有字尾子串,在模式串中與之匹配的另乙個子串的位置。同時預計算模式串中(同長度的)字尾子串與字首子串是否匹配並記錄。在具體操作中直接使用,大大提高效率。

3.如何快速記錄模式串字尾子串匹配的另乙個子串位置,以及模式串(相同長度)字首與字尾子串石否匹配呢?先用乙個suffix陣列,下標值k為字尾子串的長度,從模式串下標為i(0~m-2)的字元為最後乙個字元,查詢這個子串是否與字尾子串匹配,若匹配則將子串起始位置的下標值j賦給suffix[k]。若j為0,說明這個匹配子串的起始位置為模式串的起始位置,則用乙個陣列prefix,將prefix[k]設為true,否則設為false。k從0到m(模式串的長度)於是就得到了模式串所有字首與字尾子串的匹配情況。

// b表示模式串,m表示長度,suffix,prefix陣列事先申請好了

private

void

generategs

(char

b,int m,

int[

] suffix,

boolean

prefix)

for(

int i =

0; i < m -1;

++i)

if(j ==-1

) prefix[k]

=true

;//如果公共字尾子串也是模式串的字首子串

}}

bm演算法完整版

// a,b表示主串和模式串;n,m表示主串和模式串的長度。

public

intbm

(char

a,int n,

char

b,int m)

if(j <0)

int x = j - bc[

(int

)a[i+j]];

int y =0;

if(j < m-1)

//好字尾和壞字元中最長的

i = i + math.

max(x, y);}

return-1

;}// j表示壞字元對應的模式串中的字元下標; m表示模式串長度

private

intmovebygs

(int j,

int m,

int[

] suffix,

boolean

prefix)

}return m;

}

grep命令 文字編輯器查詢功能

字串匹配 BM演算法

bm演算法 1 三個shift函式 d1,d2,d3,函式的作用是決定當匹配不成功時視窗的移動位數。1 d1 字尾u在模式串p中的另乙個位置是最右出現位置是j 不包括在模式串尾的出現 文字串的視窗安全移動方法是將視窗移動m j字元,使文字中的u與模式串中最右邊的u的出現位置相對齊。對模式中的每個字尾...

BM演算法 字串匹配演算法

思想 使用啟發式規則,通過每次的失敗的匹配嘗試,演算法都能根據這些資訊來排除盡可能多的無法匹配的位置 為什麼說是每次呢,因為每次的情況可能不一樣,通過資訊來跳過啟發式規則的得到的步數 目的 利用啟發式規則,盡可能多跳過無法匹配的位置,從而達到更高的效率 方法 壞字元規則和好字尾規則,取其中移動步數較...

字串匹配(中) BM演算法

壞字串規則 問題 si xi可能是負數,示例如下 0 3 解決方案 好字尾規則 好字尾規則 字首子串 類似字尾子串 規則選取 實現 主串a,模式串b function bm a,b for let i 0 i let suffix let prefix generategs b,suffix,pre...