AC自动机(Aho-Corasick算法自动机)是一种多模字符串匹配算法,可以同时匹配多个关键词。相比于传统的逐个字符串匹配算法,AC自动机在处理大量关键词时的效率更高。下面我们将详细解析AC自动机的原理、构建过程以及应用实例。
AC自动机的基本原理是利用类似Trie树(字典树)的结构存储所有的关键词,并在Trie树的每个节点上附加一个指向失败指针的数组,用于解决当当前字符不匹配时如何跳转的问题。失败指针指向的节点是Trie树中当前节点的前缀节点中最长的、同时也是当前字符串的后缀的节点。
构建AC自动机的基本步骤包括:
1. 构建Trie树,将所有关键词插入Trie树中。
2. 计算每个节点的失败指针。
首先,我们实现一个基础的AC自动机,包括Trie树的构建、失败指针的计算以及搜索函数。代码如下。
#include <iostream>
#include <queue>
#include <vector>
#include <string>
using namespace std;
const int MAXN = 1e5 + 5;
const int ALPHABET_SIZE = 26;
struct TrieNode {
TrieNode* children[ALPHABET_SIZE];
TrieNode* fail;
bool isEnd;
int idx; // 存储关键词的索引
TrieNode() {
fail = nullptr;
isEnd = false;
for (int i = 0; i < ALPHABET_SIZE; i++) {
children[i] = nullptr;
}
}
};
class ACAutomaton {
private:
TrieNode* root;
void insert(string& word) {
TrieNode* node = root;
for (char ch : word) {
int index = ch - 'a';
if (node->children[index] == nullptr) {
node->children[index] = new TrieNode();
}
node = node->children[index];
}
node->isEnd = true;
}
void build() {
queue<TrieNode*> q;
root->fail = root;
for (int i = 0; i < ALPHABET_SIZE; i++) {
if (root->children[