一種多模式串匹配算法,該算法在1975年產生於貝爾實驗室,是著名的多模式匹配算法之一。php
簡單的說,KMP用來在一篇文章中匹配一個模式串;但若是有多個模式串,須要在一篇文章中把出現過的模式串都匹配出來,就須要Aho-Corasick automaton算法了。html
個人理解: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樹進行匹配了。
匹配過程分兩種狀況:
對照上圖,看一下模式匹配這個詳細的流程,其中模式串爲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算法的匹配也是很是類似,固然這一步就很是靈活了,咱們須要經過多作題來提升熟練度。
假設有N個模式串,平均長度爲L;文章長度爲M。
創建Trie樹:O(N*L)
創建fail指針:O(N*L)
模式匹配:O(M*L) (注:之因此要乘以一個L,是由於在統計的時候須要順着鏈回溯到root結點)
因此,總時間複雜度爲:O( (N+M)*L )
Entry:
synthesize problems: