热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

P3796AC自动机强化版题解-Aho-CorasickAlgorithm

本文提供了一个关于AC自动机(Aho-CorasickAlgorithm)的详细解析与实现方法,特别针对P3796题目进行了深入探讨。文章不仅涵盖了AC自动机的基本概念,还重点讲解了如何通过构建失败指针(failpointer)来提高字符串匹配效率。

题目链接


P3796 AC自动机强化版题解 - Aho-Corasick Algorithm


解题思路


本题旨在通过AC自动机解决多模式串匹配问题。AC自动机是一种高效的字符串匹配算法,它能够在O(n + m)的时间复杂度内完成模式串的预处理和文本串的搜索,其中n是所有模式串的总长度,m是文本串的长度。


AC自动机的核心在于失败指针(fail pointer)的构建。失败指针用于在当前路径无法继续匹配时,快速跳转至一个可能的匹配起点,从而避免重复扫描文本串。具体来说,当在某个节点上匹配失败时,失败指针会指向一个能够继续匹配的节点,该节点对应的字符串是当前节点前缀的最大公共后缀。


AC代码


#include 
#include

#define MAXN 100010
#define MAXM 1000010
#define MAXL 75

int ac[MAXN][26], cnt = 1;
int queue[MAXN], fail[MAXN], end[MAXN];
char patterns[MAXL][MAXL], text[MAXM];

struct Result {
int index, count;
} results[500], temp;

void insertPattern(const char *pattern, int length, int index) {
int node = 0;
for (int i = 0; i int c = pattern[i] - 'a';
if (!ac[node][c]) ac[node][c] = cnt++;
node = ac[node][c];
}
end[node] = index;
}

void buildFailPointers() {
int head = 0, tail = 0;
for (int i = 0; i <26; ++i) {
if (ac[0][i]) {
queue[tail++] = ac[0][i];
fail[ac[0][i]] = 0;
}
}
while (head int current = queue[head++];
for (int i = 0; i <26; ++i) {
if (ac[current][i]) {
fail[ac[current][i]] = ac[fail[current]][i];
queue[tail++] = ac[current][i];
} else {
ac[current][i] = ac[fail[current]][i];
}
}
}
}

void searchText(const char *text, int length) {
int node = 0;
for (int i = 0; i node = ac[node][text[i] - 'a'];
for (int j = node; j; j = fail[j]) {
if (end[j]) {
results[end[j]].count++;
}
}
}
}

int compare(const void *a, const void *b) {
return ((Result *)b)->count - ((Result *)a)->count;
}

int main() {
int n;
while (scanf("%d", &n) != EOF && n) {
cnt = 1;
for (int i = 1; i <= n; ++i) {
scanf("%s", patterns[i]);
insertPattern(patterns[i], strlen(patterns[i]), i);
results[i].index = i;
results[i].count = 0;
}
buildFailPointers();
scanf("%s", text);
searchText(text, strlen(text));
qsort(results + 1, n, sizeof(Result), compare);
printf("%d\n", results[1].count);
printf("%s\n", patterns[results[1].index]);
for (int i = 2; i <= n; ++i) {
if (results[i].count != results[i - 1].count) break;
printf("%s\n", patterns[results[i].index]);
}
memset(end, 0, sizeof(int) * cnt);
memset(fail, 0, sizeof(int) * cnt);
memset(ac, 0, sizeof(ac));
}
return 0;
}

推荐阅读
  • 本文介绍如何在 C++ 中使用链表结构存储和管理数据。通过具体示例,展示了静态链表的基本操作,包括节点的创建、链接及遍历。 ... [详细]
  • 查找最小值的操作是很简单的,只需要从根节点递归的遍历到左子树节点即可。当遍历到节点的左孩子为NULL时,则这个节点就是树的最小值。上面的树中,从根节点20开始,递归遍历左子 ... [详细]
  • 哈密顿回路问题旨在寻找一个简单回路,该回路包含图中的每个顶点。本文将介绍如何判断给定的路径是否构成哈密顿回路。 ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • JavaScript 中创建对象的多种方式
    本文介绍了 JavaScript 中创建对象的几种常见方法,包括字面量形式、构造函数、原型对象等。每种方法都有其特点和适用场景,通过对比分析,帮助开发者选择最适合的方式。 ... [详细]
  • 本文探讨了在使用Selenium进行自动化测试时,由于webdriver对象实例化位置不同而导致浏览器闪退的问题,并提供了详细的代码示例和解决方案。 ... [详细]
  • 算法题解析:最短无序连续子数组
    本题探讨如何通过单调栈的方法,找到一个数组中最短的需要排序的连续子数组。通过正向和反向遍历,分别使用单调递增栈和单调递减栈来确定边界索引,从而定位出最小的无序子数组。 ... [详细]
  • 本文探讨了使用C#在SQL Server和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。 ... [详细]
  • 在项目部署后,Node.js 进程可能会遇到不可预见的错误并崩溃。为了及时通知开发人员进行问题排查,我们可以利用 nodemailer 插件来发送邮件提醒。本文将详细介绍如何配置和使用 nodemailer 实现这一功能。 ... [详细]
  • 本文详细探讨了JavaScript中的作用域链和闭包机制,解释了它们的工作原理及其在实际编程中的应用。通过具体的代码示例,帮助读者更好地理解和掌握这些概念。 ... [详细]
  • Python 内存管理机制详解
    本文深入探讨了Python的内存管理机制,涵盖了垃圾回收、引用计数和内存池机制。通过具体示例和专业解释,帮助读者理解Python如何高效地管理和释放内存资源。 ... [详细]
  • C#设计模式学习笔记:观察者模式解析
    本文将探讨观察者模式的基本概念、应用场景及其在C#中的实现方法。通过借鉴《Head First Design Patterns》和维基百科等资源,详细介绍该模式的工作原理,并提供具体代码示例。 ... [详细]
  • Appium + Java 自动化测试中处理页面空白区域点击问题
    在进行移动应用自动化测试时,有时会遇到某些页面没有返回按钮,只能通过点击空白区域返回的情况。本文将探讨如何在Appium + Java环境中有效解决此类问题,并提供详细的解决方案。 ... [详细]
  • 如何清除Chrome浏览器地址栏的特定历史记录
    在使用Chrome浏览器时,你可能会发现地址栏保存了大量浏览记录。有时你可能希望删除某些特定的历史记录而不影响其他数据。本文将详细介绍如何单独删除地址栏中的特定记录以及批量清除所有历史记录的方法。 ... [详细]
  • 利用Selenium与ChromeDriver实现豆瓣网页全屏截图
    本文介绍了一种使用Selenium和ChromeDriver结合Python代码,轻松实现对豆瓣网站进行完整页面截图的方法。该方法不仅简单易行,而且解决了新版Selenium不再支持PhantomJS的问题。 ... [详细]
author-avatar
陈芝麻烂谷子我勒个去
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有