AC 自動機是多模式字符串匹配的經典算法,構建 Trie + 失敗指標,可在 O(n + m + z) 時間內同時匹配多個模式(n=文本長度,m=模式總長,z=匹配數)。本文呈現一個生產級 C++17 實現,支援 Unicode、重疊匹配控制、全詞匹配、大小寫不敏感、區間樹去重等進階特性,代碼結構模塊化,可直接集成項目。
| 組件 | 職責 | 關鍵模板參數 |
|---|---|---|
interval / interval_tree | 區間管理與重疊去重 | T (需支援 get_start/end) |
emit | 匹配結果承載(區間+關鍵詞) | CharType |
token | 分詞輸出(片段/匹配) | CharType |
state | Trie 節點(轉移、失敗指標、輸出集合) | CharType |
basic_trie | 核心引擎(構建、查詢、分詞) | CharType |
trie (char)、wtrie (wchar_t) 開箱即用case_insensitive():大小寫不敏感remove_overlaps():區間樹去重,保留最長匹配only_whole_words():邊界字符檢查,全詞匹配parse_text():返回 emit 列表(位置+關鍵詞)tokenise():返回 token 序列(匹配/非匹配片段交替),適合高亮/替換insert(keyword) 逐字符建節點,終點記錄 emitfailure 指向最長真後綴對應節點,合併 emit 集合next_state(c) 跳轉,失敗時沿 failure 回退至根#include "aho_corasick.hpp"
using namespace aho_corasick;
int main() {
trie ac;
ac.insert("he"); ac.insert("she"); ac.insert("his"); ac.insert("hers");
ac.remove_overlaps().case_insensitive(); // 配置
string text = "ushers";
auto emits = ac.parse_text(text);
for (auto& e : emits)
cout << "[" << e.get_start() << "," << e.get_end() << "] " << e.get_keyword() << endl;
// 輸出:
// [1,2] he
// [0,2] she
// [2,5] hers
// [3,5] he (若未去重)
return 0;
}
unique_ptr 管理 Trie 節點,無洩漏interval_tree::remove_overlaps() 以 O(k log k) 去除重疊,保留最長匹配isalpha 判斷詞邊界,支援全詞匹配| 階段 | 時間複雜度 | 空間複雜度 |
|---|---|---|
| 構建 Trie | O(m) | O(m × |Σ|) |
| 構建失敗指標 | O(m × |Σ|) | O(m) |
| 查詢 | O(n + z) | O(1) 額外 |
| 去重 | O(z log z) | O(z) |
完整頭文件 aho_corasick.hpp 含所有模板實現(約 500 行),採用 MIT 許可證,可直接複製到項目 include/ 目錄使用。