What's Aho-Corasick automaton?
一種多模式串匹配算法,該算法在1975年產生於貝爾實驗室,是著名的多模式匹配算法之一。
簡單的說,KMP用來在一篇文章中匹配一個模式串;但如果有多個模式串,需要在一篇文章中把出現過的模式串都匹配出來,就需要Aho-Corasick automaton算法了。
My Understanding About Aho-Corasick automaton
我的理解:Aho-Corasick automaton = Trie + KMP
在KMP算法中,匹配單個字符的時候,我們只需要按照文本線性的掃一遍,然后中途失配的時候,next數組會引導k回溯到正確的位置進行下一步的匹配。
但是多個模式串的時候要怎么匹配呢?Trie樹不就是一個多模式的匹配嗎,如果我們將KMP和Trie數結合起來,是不是會有意想不到的效果呢?
有了這些思考,AC自動機算法就這樣產生了。
在AC自動機中,我們首先將每一個模式串插入到Trie樹中去,建立一棵Trie樹,然后構建fail指針,fail指針,顧名思義,就是當匹配失敗的時候,用來引導k回溯的一個插穿在Trie樹的各個節點之間的一些指針,就和KMP算法中的next數組是一樣的道理。
關於fail指針的構建,推薦看一下李翔大神的PPT。
ppt下載鏈接:
http://wenku.baidu.com/view/93af2c936bec0975f465e2f1.html
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:
- Hdu 2222
- Hdu 3695 Computer Virus on Planet Pandora
- Poj 4052 Hrinity (金華邀請賽I)
- Zoj 3430 Detect the Virus
- Spoj 7758. Growing Strings
- Hdu 4417 GRE Words
- Hnu 10104 病毒
- Hnu 11187 Emoticons :-)
- Zoj 3545 Rescue the Rabbit
- Hdu 3341 Lost's revenge
- Zoj 3535 Gao the String II
- Hdu 3962 Microgene
- 大視野 2434 阿狸的打字機
- Hdu 3247 Resource Archiver
- Zoj 3494 BCD Code
synthesize problems:
- TSP HDU 3341. Lost's revenge HDU 3247. Resource Archiver
- 狀態壓縮、可變進制編碼 HOJ 2951. Writing Robot / HDU 3505
- 最大權閉合子圖 ZeroJudge b179.Cans
- 自動機 DP、fail 指針轉移 CodeChef July Challenge 2012. Favourite Numbers
- 二分答案、數位 DP、構造方案 Andrew Stankevich's Contest #2, Problem A, Non Absorbing DFA
- 預處理、DP、高精度 SPOJ. 9941. GRE Words / HDU 4117