在处理大量文本中查找多个关键词的问题时,AC自动机(Aho-Corasick Automaton)是一种非常高效的C++字符串匹配工具。它能在一次扫描中同时匹配多个模式串,时间复杂度接近线性,非常适合用于敏感词过滤、病毒特征码检测等场景。
AC自动机是由 Alfred Aho 和 Margaret Corasick 在 1975 年提出的多模式匹配算法。它结合了 Trie 树(字典树)和 KMP 算法中的失败指针(failure function)思想,构建一个有限状态自动机,从而在输入文本中快速定位所有模式串的出现位置。

下面我们用 C++ 一步步实现 AC 自动机。即使你是编程小白,也能跟着理解。
struct Node { unordered_map<char, Node*> children; // 子节点映射 Node* fail = nullptr; // 失败指针 vector<string> output; // 以该节点结尾的模式串 Node() {}};将所有模式串插入到 Trie 中:
void insertPattern(Node* root, const string& pattern) { Node* curr = root; for (char c : pattern) { if (curr->children.find(c) == curr->children.end()) { curr->children[c] = new Node(); } curr = curr->children[c]; } curr->output.push_back(pattern); // 记录完整模式串}使用广度优先搜索(BFS)来设置每个节点的 fail 指针:
void buildFailureLinks(Node* root) { queue<Node*> q; // 初始化:根的所有子节点的 fail 指向 root for (auto& kv : root->children) { kv.second->fail = root; q.push(kv.second); } while (!q.empty()) { Node* curr = q.front(); q.pop(); for (auto& kv : curr->children) { char c = kv.first; Node* child = kv.second; // 找到 curr 的 fail 链中第一个有字符 c 子节点的节点 Node* f = curr->fail; while (f != root && f->children.find(c) == f->children.end()) { f = f->fail; } if (f->children.find(c) != f->children.end()) { child->fail = f->children[c]; } else { child->fail = root; } // 合并输出:如果 fail 节点有输出,也加入当前节点 if (!child->fail->output.empty()) { child->output.insert(child->output.end(), child->fail->output.begin(), child->fail->output.end()); } q.push(child); } }}遍历文本,利用自动机进行匹配:
vector<pair<int, string>> search(const string& text, Node* root) { vector<pair<int, string>> matches; Node* curr = root; for (int i = 0; i < text.size(); ++i) { char c = text[i]; // 若当前节点没有 c 的子节点,则沿 fail 链回退 while (curr != root && curr->children.find(c) == curr->children.end()) { curr = curr->fail; } if (curr->children.find(c) != curr->children.end()) { curr = curr->children[c]; } // 检查当前节点及其 fail 链上的所有输出 for (const string& pattern : curr->output) { matches.push_back({i - (int)pattern.size() + 1, pattern}); } } return matches;}#include <iostream>#include <vector>#include <queue>#include <unordered_map>#include <string>using namespace std;// 上面定义的 Node、insertPattern、buildFailureLinks、search 函数int main() { vector<string> patterns = {"he", "she", "his", "hers"}; string text = "ushers"; Node* root = new Node(); // 插入所有模式串 for (const string& p : patterns) { insertPattern(root, p); } // 构建失败指针 buildFailureLinks(root); // 搜索文本 auto results = search(text, root); for (auto& match : results) { cout << "Found \"" << match.second << "\" at position " << match.first << endl; } return 0;}通过本文,你已经掌握了 AC自动机 的基本原理和 C++字符串匹配 的完整实现。这种 多模式匹配算法 在实际工程中应用广泛,性能远超逐个使用 KMP 或暴力匹配。建议你动手敲一遍代码,加深理解,并尝试优化(例如使用数组代替 map 提高速度)。
记住,掌握 AC自动机实现 不仅能提升你的算法能力,还能为处理大规模文本匹配任务打下坚实基础!
本文由主机测评网于2025-12-12发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025126495.html