字串匹配的Boyer Moore演算法

2021-07-02 04:31:41 字數 1682 閱讀 5120

首先,」字串」與」搜尋詞」頭部對齊,從尾部開始比較。

這是乙個很聰明的想法,因為如果尾部字元不匹配,那麼只要一次比較,就可以知道前7個字元(整體上)肯定不是要找的結果。

我們看到,」s」與」e」不匹配。這時,」s」就被稱為」壞字元」(bad character),即不匹配的字元。我們還發現,」s」不包含在搜尋詞」example」之中,這意味著可以把搜尋詞直接移到」s」的後一位。

3. 依然從尾部開始比較,發現」p」與」e」不匹配,所以」p」是」壞字元」。但是,」p」包含在搜尋詞」example」之中。所以,將搜尋詞後移兩位,兩個」p」對齊。

4. 我們由此總結出」壞字元規則」:

後移位數 = 壞字元的位置 - 搜尋詞中的上一次出現位置

如果」壞字元」不包含在搜尋詞之中,則上一次出現位置為 -1。

以」p」為例,它作為」壞字元」,出現在搜尋詞的第6位(從0開始編號),在搜尋詞中的上一次出現位置為4,所以後移 6 - 4 = 2位。再以前面第二步的」s」為例,它出現在第6位,上一次出現位置是 -1(即未出現),則整個搜尋詞後移 6 - (-1) = 7位。

5. 依然從尾部開始比較,」e」與」e」匹配。

6. 比較前面一位,」le」與」le」匹配。

7. 比較前面一位,」ple」與」ple」匹配。

8. 比較前面一位,」mple」與」mple」匹配。我們把這種情況稱為」好字尾」(good suffix),即所有尾部匹配的字串。注意,」mple」、」ple」、」le」、」e」都是好字尾。

9. 比較前一位,發現」i」與」a」不匹配。所以,」i」是」壞字元」。

10.

根據」壞字元規則」,此時搜尋詞應該後移 2 - (-1)= 3 位。問題是,此時有沒有更好的移法?

11.

我們知道,此時存在」好字尾」。所以,可以採用」好字尾規則」:

後移位數 = 好字尾的位置 - 搜尋詞中的上一次出現位置

舉例來說,如果字串」abcdab」的後乙個」ab」是」好字尾」。那麼它的位置是5(從0開始計算,取最後的」b」的值),在」搜尋詞中的上一次出現位置」是1(第乙個」b」的位置),所以後移 5 - 1 = 4位,前乙個」ab」移到後乙個」ab」的位置。

再舉乙個例子,如果字串」abcdef」的」ef」是好字尾,則」ef」的位置是5 ,上一次出現的位置是 -1(即未出現),所以後移 5 - (-1) = 6位,即整個字串移到」f」的後一位。

這個規則有三個注意點:

(1)」好字尾」的位置以最後乙個字元為準。假定」abcdef」的」ef」是好字尾,則它的位置以」f」為準,即5(從0開始計算)。

(2)如果」好字尾」在搜尋詞中只出現一次,則它的上一次出現位置為-1。比如,」ef」在」abcdef」之中只出現一次,則它的上一次出現位置為-1(即未出現)。   

(3)如果」好字尾」有多個,則除了最長的那個」好字尾」,其他」好字尾」的上一次出現位置必須在頭部。比如,假定」babcdab」的」好字尾」是」dab」、」ab」、」b」,請問這時」好字尾」的上一次出現位置是什麼?回答是,此時採用的好字尾是」b」,它的上一次出現位置是頭部,即第0位。這個規則也可以這樣表達:如果最長的那個」好字尾」只出現一次,則可以把搜尋詞改寫成如下形式進行位置計算」(da)babcdab」,即虛擬加入最前面的」da」。

字串匹配

題目描述 讀入資料string 然後讀入乙個短字串。要求查詢string 中和短字串的所有匹配,輸出行號 匹配字串。匹配時不區分大小寫,並且可以有乙個用中括號表示的模式匹配。如 aa 123 bb 就是說aa1bb aa2bb aa3bb都算匹配。輸入 輸入有多組資料。每組資料第一行輸入n 1 n ...

字串匹配

time limit 1000ms memory limit 65536k 給定兩個字串string1和string2,判斷string2是否為string1的子串。輸入包含多組資料,每組測試資料報含兩行,第一行代表string1,第二行代表string2,string1和string2中保證不出現...

字串匹配

面試題 給一串很長的字串,要求找到符合要求的字串,例如目的串 123 1 3 2 12 3 這些都要找出來 思路一 利用兩層迴圈,逐個查詢目的串中的字元,比如先查詢字元 1 是否在長字串中,再查詢 2 是否在長字串中,直到目的串遇到 0 是 include include include int m...