AC自動機-算法詳解

What's Aho-Corasick automaton?

  一種多模式串匹配算法,該算法在1975年產生於貝爾實驗室,是著名的多模式匹配算法之一。php

  簡單的說,KMP用來在一篇文章中匹配一個模式串;但若是有多個模式串,須要在一篇文章中把出現過的模式串都匹配出來,就須要Aho-Corasick automaton算法了。html

My Understanding About Aho-Corasick automaton

    個人理解:Aho-Corasick automaton = Trie + KMP算法

  在KMP算法中,匹配單個字符的時候,咱們只須要按照文本線性的掃一遍,而後中途失配的時候,next數組會引導k回溯到正確的位置進行下一步的匹配。數組

  可是多個模式串的時候要怎麼匹配呢?Trie樹不就是一個多模式的匹配嗎,若是咱們將KMP和Trie數結合起來,是否是會有意想不到的效果呢?ui

  有了這些思考,AC自動機算法就這樣產生了。編碼

  在AC自動機中,咱們首先將每個模式串插入到Trie樹中去,創建一棵Trie樹,而後構建fail指針,fail指針,顧名思義,就是當匹配失敗的時候,用來引導k回溯的一個插穿在Trie樹的各個節點之間的一些指針,就和KMP算法中的next數組是同樣的道理。spa

  關於fail指針的構建,推薦看一下李翔大神的PPT。3d

  ppt下載連接:指針

    http://wenku.baidu.com/view/93af2c936bec0975f465e2f1.htmlcode

1.構建Trie樹

  

  

2.在Trie樹上構建fail指針

  

  

 

 

 

 

 

 

 

 

構建完fail指針後,咱們就用文章來對這棵Trie樹進行匹配了。

  匹配過程分兩種狀況:

  • 當前字符匹配,表示從當前節點沿着樹邊有一條路徑能夠到達目標字符,此時只需沿該路徑走向下一個節點繼續匹配便可,目標字符串指針移向下個字符繼續匹配;
  • 當前字符不匹配,則去當前節點fail指針所指向的字符繼續匹配,匹配過程隨着指針指向root結束。重複這2個過程當中,直到模式串走到結尾爲止。

  對照上圖,看一下模式匹配這個詳細的流程,其中模式串爲yasherhs。

  對於i=0,1。Trie中沒有對應的路徑,故不作任何操做;i=2,3,4時,指針p走到左下節點e。

  由於節點e的count信息爲1,因此cnt+1,而且講節點e的count值設置爲-1,表示改單詞已經出現過了,防止重複計數,最後temp指向e節點的失敗指針所指向的節點繼續查找,以此類推,最後temp指向root,退出while循環,這個過程當中count增長了2,表示找到了2個單詞she和he。

  當i=5時,程序進入第5行,p指向其失敗指針的節點,也就是右邊那個e節點,隨後在第6行指向r節點,r節點的count值爲1,從而count+1,循環直到temp指向root爲止。

  最後i=6,7時,找不到任何匹配,匹配過程結束。

匹配過程總結:

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

當讀入的字符,在分支中不存在時,遞歸走Fail指針。若是走Fail指針走到了root節點,則跳過該字符,處理下一個字符。
由於AC自動機是沿着輸入文本的最長後綴移動的,因此在讀取完全部輸入文本後,最後遞歸走Fail指針,直到到達根節點,這樣能夠檢測出全部的模式。
這個過程和KMP算法的匹配也是很是類似,固然這一步就很是靈活了,咱們須要經過多作題來提升熟練度。

Time Complexity Analyse

假設有N個模式串,平均長度爲L;文章長度爲M。

創建Trie樹:O(N*L)

創建fail指針:O(N*L)

模式匹配:O(M*L) (注:之因此要乘以一個L,是由於在統計的時候須要順着鏈回溯到root結點)

因此,總時間複雜度爲:O( (N+M)*L )

Some Good Selection Of Standard Exercise

Entry:

synthesize problems:

相關文章
相關標籤/搜索