1. 程式人生 > >Aho-Corasick 多模式匹配算法、AC自動機詳解

Aho-Corasick 多模式匹配算法、AC自動機詳解

實現 輸出 dfa 輸入 開始 img 添加 每一個 jpg

Aho-Corasick算法是多模式匹配中的經典算法,目前在實際應用中較多。

Aho-Corasick算法對應的數據結構是Aho-Corasick自動機,簡稱AC自動機。

搞編程的一般都應該知道自動機FA吧,具體細分為:確定性有限狀態自動機(DFA)和非確定性有限狀態自動機NFA。普通的自動機不能進行多模式匹配,AC自動機增加了失敗轉移,轉移到已經輸入成功的文本的後綴,來實現。

1.多模式匹配

  多模式匹配就是有多個模式串P1,P2,P3...,Pm,求出所有這些模式串在連續文本T1....n中的所有可能出現的位置。

  例如:求出模式集合{"nihao","hao","hs","hsr"}在給定文本"sdmfhsgnshejfgnihaofhsrnihao"中所有可能出現的位置

2.Aho-Corasick算法  

  使用Aho-Corasick算法需要三步:

  1.建立模式的Trie

  2.給Trie添加失敗路徑

  3.根據AC自動機,搜索待處理的文本

  下面說明這三步:

2.1建立多模式集合的Trie

  Trie樹也是一種自動機。對於多模式集合{"say","she","shr","he","her"},對應的Trie樹如下,其中紅色標記的圈是表示為接收態:

  技術分享

2.2為多模式集合的Trie樹添加失敗路徑,建立AC自動機

  構造失敗指針的過程概括起來就一句話:設這個節點上的字母為C,沿著他父親的失敗指針走,直到走到一個節點,他的兒子中也有字母為C的節點。然後把當前節點的失敗指針指向那個字母也為C的兒子。如果一直走到了root都沒找到,那就把失敗指針指向root。

  使用廣度優先搜索BFS,層次遍歷節點來處理,每一個節點的失敗路徑。  

  特殊處理:第二層要特殊處理,將這層中的節點的失敗路徑直接指向父節點(也就是根節點)

技術分享

2.3根據AC自動機,搜索待處理的文本

  從root節點開始,每次根據讀入的字符沿著自動機向下移動。

  當讀入的字符,在分支中不存在時,遞歸走失敗路徑。如果走失敗路徑走到了root節點,則跳過該字符,處理下一個字符。

  因為AC自動機是沿著輸入文本的最長後綴移動的,所以在讀取完所有輸入文本後,最後遞歸走失敗路徑,直到到達根節點,這樣可以檢測出所有的模式。

3.Aho-Corasick算法代碼示例

  模式串集合:{"nihao","hao","hs","hsr"}

  待匹配文本:"sdmfhsgnshejfgnihaofhsrnihao"

  輸出:

  技術分享

(上面的兩個圖,參考網頁:http://www.cppblog.com/mythit/archive/2009/04/21/80633.html)

Aho-Corasick 多模式匹配算法、AC自動機詳解