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...