在文本处理、网络安全、生物信息学等领域,我们常常需要在一个大文本中同时查找多个关键词。如果用朴素的KMP或BF算法逐个匹配,效率会非常低。这时,AC自动机(Aho-Corasick Automaton)就派上用场了!本文将用通俗易懂的方式,教你如何用C语言从零实现一个高效的多模式匹配算法。
AC自动机是由 Alfred Aho 和 Margaret Corasick 在1975年提出的一种多模式字符串匹配算法。它结合了字典树(Trie)和KMP算法中的失败指针思想,能够在一次扫描中同时匹配多个模式串,时间复杂度为 O(n + m + z),其中 n 是文本长度,m 是所有模式串总长度,z 是匹配结果数量。
AC自动机主要由三部分组成:
struct Node { int count; // 记录以该节点结尾的模式串数量 struct Node* fail; // 失败指针 struct Node* children[26]; // 假设只处理小写字母};// 创建新节点struct Node* createNode() { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->count = 0; node->fail = NULL; for (int i = 0; i < 26; i++) { node->children[i] = NULL; } return node;} void insertPattern(struct Node* root, char* pattern) { struct Node* current = root; for (int i = 0; pattern[i] != '\0'; i++) { int index = pattern[i] - 'a'; if (current->children[index] == NULL) { current->children[index] = createNode(); } current = current->children[index]; } current->count++; // 标记此处有一个模式串结束} void buildFailPointer(struct Node* root) { struct Node* queue[1000]; int front = 0, rear = 0; // 初始化:根的所有子节点的fail指向root,并入队 for (int i = 0; i < 26; i++) { if (root->children[i] != NULL) { root->children[i]->fail = root; queue[rear++] = root->children[i]; } } // BFS构建fail指针 while (front < rear) { struct Node* current = queue[front++]; for (int i = 0; i < 26; i++) { if (current->children[i] != NULL) { struct Node* child = current->children[i]; struct Node* f = current->fail; // 沿着fail链向上找,直到找到有对应子节点的祖先 while (f != NULL && f->children[i] == NULL) { f = f->fail; } child->fail = (f == NULL) ? root : f->children[i]; // 累加输出:如果fail节点是模式串结尾,也应被计入 child->count += child->fail->count; queue[rear++] = child; } } }} int searchText(struct Node* root, char* text) { struct Node* current = root; int totalMatches = 0; for (int i = 0; text[i] != '\0'; i++) { int index = text[i] - 'a'; // 如果当前节点没有对应子节点,沿fail指针回退 while (current != root && current->children[index] == NULL) { current = current->fail; } if (current->children[index] != NULL) { current = current->children[index]; } // 累加当前节点及fail链上的所有匹配 totalMatches += current->count; } return totalMatches;} #include <stdio.h>#include <stdlib.h>#include <string.h>// 上面定义的结构体和函数...int main() { struct Node* root = createNode(); // 插入多个模式串 insertPattern(root, "he"); insertPattern(root, "she"); insertPattern(root, "his"); insertPattern(root, "hers"); // 构建失败指针 buildFailPointer(root); // 在文本中搜索 char text[] = "ahishers"; int matches = searchText(root, text); printf("Total matches: %d\n", matches); // 输出:3(包含 "his", "she", "hers") return 0;} 通过本文,你已经掌握了用C语言实现AC自动机的基本方法。这种多模式匹配算法在实际工程中非常有用,比如敏感词过滤、病毒特征码扫描等场景。虽然代码看起来有点复杂,但只要理解了Trie树和失败指针的思想,就能轻松掌握。
记住,AC自动机的关键在于:构建Trie → 设置fail指针 → 一次扫描完成所有匹配。希望这篇教程能帮助你从零开始理解和实现这个强大的算法!
本文由主机测评网于2025-12-23发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20251212073.html