字典樹問題與AC自動機

2021-08-18 12:46:44 字數 1914 閱讀 9362

利用字串的公共字首來避免無謂的字串比較,降低查詢時間。

字典樹節點:

每個節點對應乙個最大可儲存字元陣列。假設字典只存26個小寫英文本母,那麼每個節點下應該有乙個長度為最大26的陣列。換言說,可存的元素型別越多,單個節點占用記憶體越大。如果用字典樹儲存漢字,那麼每個節點必須為數千個常用漢字開闢乙個陣列作為儲存空間,占用的記憶體實在不是乙個數量級。不過trie樹就是一種用空間換時間的資料結構。

3個重要性質:

(1) 根節點不包含字元,除根節點外每乙個節點都只包含乙個字元。

(2) 從根節點到某一節點,路徑上經過的字元連線起來,為該節點對應的字串。

(3) 每個節點的所有子節點包含的字元都不相同。

優點:

trie樹中不同的關鍵字不會產生衝突。

trie樹中只有在允許乙個關鍵字關聯多個值的情況下才有類似hash碰撞發生。

trie樹不用求hash值,對短字串有更快的速度。通常,求hash值也是需要遍歷字串的(與hash函式相關)。

trie樹可以對關鍵字 按照字典序排序 (先序遍歷)。

關於查詢,有人會說hash表時間複雜度是o(1)不是更快?但是雜湊搜尋的效率取決於雜湊函式的好壞,若乙個壞的hash函式導致了很多衝突,效率不一定比trie樹高。

缺點:

空間消耗大。

應用:

1.查詢某個字串出現的次數

每個節點的count置為0,直到這個字串結束,在末尾處count++.這樣,就記錄了該字串的出現次數。

(當資料量大時,必須用字典樹,資料量小時,可採用map來做)

具體可參考:

2.查詢某個字串特定序列出現的次數(統計字首次數)。

每個節點的count初始化為0,當讀入乙個字元,則count++。這樣,查詢時,這個節點count記錄的就是從頭結點到該結點特定序列出現的次數。可以用於統計單詞的字首一類的題目。

其中1,2都可以採用hash表來做。

對(1)中的trie進行先序遍歷,將字串和出現次數存進乙個結構體,最後對這個陣列進行快速排序,時間複雜度為o(nlogn),看網上說可以利用分治+trie

+最小堆

4.實現自動補全功能

其實原理都差不多,把

字串結尾處的結點當作root

,進行先序遍歷,即可得出所有以輸入的字串為字首的答案

有關結點的描述:

ac自動機

kmp演算法是單模式串的字元匹配演算法,ac自動機是多模式串的字元匹配演算法。

例如:我們給出5個單詞,say,she,shr,he,her。給定字串為yasherhs。問多少個單詞在字串中出現過。

ac自動機的構造:

1.構造一棵trie,作為ac自動機的搜尋資料結構。

2.構造fail指標,使當前字元失配時跳轉到具有最長公共前字尾的字元繼續匹配。如同 kmp演算法一樣, ac自動機在匹配時如果當前字元匹配失敗,那麼利用fail指標進行跳轉。由此可知如果跳轉,跳轉後的串的字首,必為跳轉前的模式串的字尾並且跳轉的新位置的深度(匹配字元個數)一定小於跳之前的節點。所以我們可以利用 bfs在 trie上面進行 fail指標的求解。

3.掃瞄主串進行匹配。

struct node;

AC自動機(KMP 字典樹)

ac自動機 kmp 字典樹 題目 輸入n個串,判斷有多少個搜尋串的子串 in out 1 47a ababc abcd abcde abcdef abcdefg abcd includeusing namespace std char str 1000000 100 struct node root...

字典樹哇 AC自動機哇

字典樹 原理 按照每個根向下發散 形成一棵 樹 這個題 需要在每乙個字母處都做統計 求字首單詞 開乙個 二維陣列和ant來 模擬樹 root開始為0 作為 起點 t str i a 作為分支 關鍵就是 ant 這是形成樹的關鍵 ant用來區分每乙個節點 這樣二維陣列 tree才能 真正構建完成 很神...

字典樹哇 AC自動機哇

字典樹 原理 按照每個根向下發散 形成一棵 樹 這個題 需要在每乙個字母處都做統計 求字首單詞 開乙個 二維陣列和ant來 模擬樹 root開始為0 作為 起點 t str i a 作為分支 關鍵就是 ant 這是形成樹的關鍵 ant用來區分每乙個節點 這樣二維陣列 tree才能 真正構建完成 很神...