ac自動機解決的問題是,多個單詞在一篇文章中出現頻率的多對一類的問題。
解決問題的步驟是:1、建立trie樹;2、構造失敗指標;3、模式匹配。
構造失敗指標是關鍵步驟,能夠降低匹配的複雜度,有類似於kmp演算法中next陣列的作用,只是比next在匹配時要麻煩一點,但是可以先預處理出next陣列。失敗指標,顧名思義,即在匹配失敗的時候下一步的位置,如果不用ac自動機,則會回溯到根節點,這樣必然是不明♂智的。可以利用的佇列建立失敗指標。
queue
q;void buildacautomation(trienode *root)
}}//end while
}int query(char x, trienode *root) //calculate all the words' exsitence
i++;
}return res;}
看乙個具體的問題
hdu 2222
題意 給定n個模式串 統計在乙個長為m的主串裡出現了多少個模式串
kmp演算法可以做 複雜度為o(mn)
結合kmp演算法和trie樹 ac自動機可以很好的解決這個問題
ac自動機的第一步是把所有模式串建成乙個trie
比如有模式串
第一步.建立相應的trie
主串為shersay
和kmp演算法的策略基本相同
ac自動機是從根節點開始根據主串的字母在trie上走
運氣很好 我們只要在trie上走三步就配到乙個串she
正當我們想要繼續的時候 發現下乙個字母是s 在當前節點x上不能再向下了
只好再回頭跳到根節點繼續配
顯然這樣不斷地 匹配就向下 不匹配就回溯到根 是可以得到正解的
但是最壞複雜度還是o(mn)
我們回想kmp演算法 既然要回溯 不如回的少一點
我們在she配好之後 抬頭一看 有個單詞的字首是he 正好是she的字尾
我們就跳到he的詞尾節點 繼續配這樣就減少了運算量
假設還有e這個單詞怎麼辦 我們顯然是不往上回溯的 因為字尾e沒有字尾he長嘛
我們發現到了新的節點可以配出r這個字母 就繼續向下 走了一步又發現無路可走了
抬頭一看 什麼也沒發現 無奈之下回到根節點繼續配 又欣喜的發現say可以配了
如此就匹配完了 由於走到了四個模式串的詞尾
所以這個主串出現了 she he her say四個串
回顧我們的探索歷程 我們借鑑了kmp的思路 利用了回溯來降低運算量
從she詞尾到he詞尾 從her詞尾到root 有兩次回溯
這就是ac自動機的核心思想 fail指標 顧名思義就是匹配失敗了 回溯到**繼續
這個和kmp的next函式十分類似
回憶kmp的next函式我們是通過線性遞推來構造的
trie是一棵樹 我們就通過bfs來實現吧
下圖是構造好fail指標的ac自動機
第二步.構建fail指標
由於根節點的特殊性 我們不好把它的兒子和其他節點統一處理 於是就乙個迴圈解決
然後開始bfs 我們把隊首的兒子都依次處理好然後入隊即可
尋找兒子的fail指標 和kmp類似 從父親開始不斷的利用長輩的fail指標回溯
直到乙個長輩節點有乙個兒子 和 父親的這個兒子一樣為止
把兒子的fail指標連向長輩的兒子
如果走到根節點都沒有這樣的長輩 就把fail指向root
隊空就結束了
注意到虛線代表的串 前面的串是後面串的字尾
理解這個bfs就不難了
第三步.匹配
就是根據主串在自動機上走
匹配成功就向下走一步 不成功就沿著fail指標回溯
複雜度達到了o(m)
很好理解 注意統計的細節即可
AC自動機 建立nlogn個AC自動機
string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...
AC自動機及字尾自動機
ac自動機是一種基於trie樹的演算法,其本質和kmp上的處理很相似。trie樹結構 kmp轉移思路 ac自動機組要由三個部分組成 trie樹的建立 fail指標的匹配 對ac自動機的詢問 每次建立自動機會有一次初始化 ac自動機類 struct node node結構體 struct ac voi...
AC自動機演算法
ac自動機簡介 首先簡要介紹一下ac自動機 aho corasickautomation,該演算法在1975年產生於貝爾實驗室,是著名的多模匹配演算法之一。乙個常見的例子就是給出n個單詞,再給出一段包含m個字元的文章,讓你找出有多少個單詞在文章裡出現過。要搞懂ac自動機,先得有字典樹trie和kmp...