字串匹配演算法4 AC演算法(1)理解

2021-10-06 12:19:35 字數 2629 閱讀 7323

2. ac演算法-時間複雜度

3. ac演算法實現步驟

4. 例子說明

4.2 失效函式(f)

4.3 輸出函式(output)

4.4 完整模式匹配機(圖示)

5. 匹配例子(hisshers)

6. **實現

參考假設您有乙個文字包括 n個單詞words 和 大量關鍵字 有m 個關鍵字keywords,請問你如何快速找到所有關鍵字?

首先想到的是簡單的暴力匹配,兩個for迴圈遍歷查詢

即如下所示:

//遍歷所有單詞 n個 words

//遍歷所有關鍵字 m個 keywords

for(int i =0; i < n; i++)

}}

這樣時間複雜度為o(n*m),是非常緩慢的,

那麼:有沒有更高效的演算法實現呢?

2023年,貝爾實驗室的alfred aho和margaret corasick發現了一種只掃瞄一遍文字就能完成這項任務的演算法,該演算法依據他們的名字命名為aho-corasick匹配演算法,簡稱ac演算法

只掃瞄一遍文字就能完成這項任務的演算法

通過有限自動機巧妙地將字元比較轉化為狀態轉移

演算法的時間複雜度與關鍵字的數目無關,只跟文字長度有關,

其時間複雜度為o(n),優於o(n*m),匹配效率提公升m倍。

第一步,我們將多個關鍵字構造成乙個有限狀態模式匹配機。

第二步,我們將文字字串作為輸入送入模式匹配機進行匹配。

ac自動機本質是一顆帶狀態的字典樹

在構建模式匹配機階段,ac演算法需要建立三個核心函式,分別為

轉向函式goto

失效函式failure

輸出函式output

下面通過關鍵字來介紹匹配機構建過程

定義: 轉向函式(g):

指的是一種狀態之間的轉向關係

公式:g(pre, x) = next,狀態pre在輸入乙個字元x後轉換為狀態next,

例子:如 g(1, e) = 2。

問題:如果在模式串中不存在這個的轉換,如g(5, r),怎麼辦呢?這個需要由失效函式來處理。

定義:指的是在失效情況下狀態之間的轉向關係切換根據

根據模式含有其他模式的字首自動切換到某個狀態

上圖說明

如上圖模式串1含有模式串2的字首,當匹配到a位置時,模式串1匹配失效,則跳轉到模式串2進行匹配,而不用回到初始狀態(0號狀態)重新開始匹配。

she模式是含有hers模式的字首he,當在狀態5匹配失效時跳轉到狀態2繼續匹配。

失效跳轉狀態可通過遞迴推導獲得:

f(與狀態0直連狀態) = 0 //f(1)=f(3)=0

f(current) = g(f(pre),x) //f(4)=g(f(3),h)=g(0,h)=1

舉例說明:

比如g(5, r)=fail,g(5, r)=g(f(5),r),f(5)=g(f(4),e)=g(g(f(3),h),e)

狀態3對應字元s,沒有其他模式的字首,切換到狀態0,即f(3)=0

所以:f(5)=g(f(4),e)=g(g(f(3),h),e)=g(g(0,h),e)=g(1,e)=2,

狀態轉移圖的失效函式轉移函式:

i 	1 2 3 4 5 6 7 8 9 

f(i)0 0 0 1 2 0 3 0 3

轉移圖如下所示:

定義輸出函式: 指的是狀態和模式串之間的一種關係。

說明: output(i)=,表示當狀態機達到狀態i時,模式串p中的所有模式串已經完成匹配。比如達到狀態5,則模式串she和he匹配成功。

輸出函式如下圖所示:

假設待匹配文字為"hisshers"

那麼狀態轉移為:

0->1->6-> 7->3 -> 0->3 ->4-> 5->2 ->8->9,文字僅掃瞄了一遍,依次輸出結果"his"、「she」、「he」、「he」、「hers」。

**實現請看第篇部落格

字串匹配演算法4:ac演算法(2)**實現

字串匹配演算法 字串匹配演算法總覽

字串匹配在文字處理裡非常重要,我們採用簡潔的python 把以下演算法一一實現並講解。樸素演算法 algorithm rabin karp 演算法 有限自動機演算法 finite automation knuth morris pratt 演算法 kmp algorithm boyer moore ...

字串匹配演算法

首先引用一下另一篇文章中對字串匹配的介紹 字串匹配指的是從文字中找出給定字串 稱為模式 的乙個或所有出現的位置。本文的演算法一律輸出全部的匹配位 置。模式串在 中用x m 來表示,文字用y n 來,而所有字串都構造自乙個有限集的字母表 其大小為 根 據先給出模式還是先給出文字,字串匹配分為兩類方法 ...

字串匹配演算法

平常操作文字的時候,經常需要操作對字串進行操作。而字串中最重要的一種操作就叫匹配,字串的匹配演算法很多,人們最熟悉的莫過於kmp演算法了。今天就來談一談一些字串匹配演算法。先來說說大名鼎鼎的kmp演算法,這個演算法出現在無數的資料結構與演算法書上面。它的策略很簡單 當模式串第k個字元不匹配主串中第s...