AC自动机(查询)

news2025/3/18 16:54:46

        上面讲了AC自动机是如何建树和建自动机的,这里要讲的是AC自动机的查询和各个数组的功能和作用。

        其实AC自动机的查询和KMP算法是及其相近的,都是一个指针跑主串,另一个指针跑ne串(这里就是回跳边)。

        话都说到这了,不妨先来看看ne的真实用处吧。上次有提过,ne数组存的其实就是最长的后缀模式串,当我们找到一个字串在主串中匹配的时候,我们并不能直接继续下去,因为如果两个单词之间存在借位的情况,我们就会忽略从而导致错误,所以我们需要记录下当前字母先前能回跳的位置,这样我们才能将我们所要的字串一网打尽,和KMP其实是完全相同的。

        那么转移边呢,我们说过我们要用一个指针去遍历树,但是我们遍历树的时候一但到头了怎么办,是不是要沿着原路反回。现在我们用一个转移边就可以节省这一部分的操作,那么为什么要把转移边建在自己回跳边的儿子上呢?其实是为了契合上面所建的回跳边,这样我们的跑主串的指针就一定会是不回退的,只需要回跳边不断操作,主串完全就是一个匹配版,不需要进行复杂的操作。

        代码如下:

int query(char *s)
{
	int ans = 0;
	
	for(int k = 0, i = 0; s[k]; k ++)
	{
		i = ch[i][s[k] - 'a'];
		
		for(int j = i; j && ~cnt[j]; j = ne[j])
		{
			ans += cnt[j];
			cnt[j] = -1;
		}
	}
	
	return ans;
}

        这里需要注意,我们的计数的维护,当我们找到某一个字串后,我们会加上它在Trie树中存储的个数,同时别忘了清零,否则会多加,这里用的是位运算的小技巧。 

        贴一道例题:

https://www.luogu.com.cn/problem/P3808icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P3808

题目描述

给定 𝑛 个模式串 𝑠𝑖 和一个文本串 𝑡,求有多少个不同的模式串在文本串里出现过。
两个模式串不同当且仅当他们编号不同。

输入格式

第一行是一个整数,表示模式串的个数 𝑛。
第 2 到第 (𝑛+1) 行,每行一个字符串,第 (𝑖+1) 行的字符串表示编号为 𝑖的模式串 𝑠𝑖。
最后一行是一个字符串,表示文本串 𝑡。

输出格式

输出一行一个整数表示答案。

输入输出样例

输入 #1复制

3
a
aa
aa
aaa

输出 #1复制

3

输入 #2复制

4
a
ab
ac
abc
abcd

输出 #2复制

3

输入 #3复制

2
a
aa
aa

输出 #3复制

2

        代码如下:
 

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

int ch[N][26], cnt[N], ne[N];
int n, idx;
char s[N];

void insert(char *s)
{
	int p = 0;
	
	for(int i = 0; s[i]; i ++)
	{
		int j = s[i] - 'a';
		if(!ch[p][j])
			ch[p][j] = ++ idx;
		p = ch[p][j];
	}
	cnt[p] ++;
}

void build()
{
	queue<int> q;
	
	for(int i = 0; i < 26; i ++)
		if(ch[0][i])
			q.push(ch[0][i]);
			
	while(!q.empty())
	{
		int u = q.front();
		q.pop();
		for(int i = 0; i < 26; i ++)
		{	
			int v = ch[u][i]; 
			if(v)
			{
				ne[v] = ch[ne[u]][i];
				q.push(v);
			}
			else
				ch[u][i] = ch[ne[u]][i];
		}
	}
}

int query(char *s)
{
	int ans = 0;
	
	for(int k = 0, i = 0; s[k]; k ++)
	{
		i = ch[i][s[k] - 'a'];
		for(int j = i; j && ~cnt[j]; j = ne[j])
		{
			ans += cnt[j];
			cnt[j] = -1;
		}
	}
	
	return ans;
}

int main()
{
	cin >> n;
	
	while(n --)
	{
		cin >> s;
		
		insert(s);
	}
	
	build();
	
	cin >> s;
	
	int ans = query(s);
	
	cout << ans << endl;
}

        我发现了,其实这些看起来比较难的算法并没有用什么特别高级的东西,大多都是需要动脑想的,只要将各个数组的作用,以及特殊的定义想明白其实还是简单的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1789596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#中字节数组(byte[])末尾继续添加字节的示例

方法一&#xff1a;使用List 使用List可以很容易地在末尾添加字节&#xff0c;然后如果需要&#xff0c;可以将其转换回byte[]。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Lin…

【C++小知识】为什么C语言不支持函数重载,而C++支持

为什么C语言不支持函数重载&#xff0c;而C支持 编译链接过程函数名修饰过程总结 在了解C函数重载前&#xff0c;如果对文件的编译与链接不太了解。可以看看我之前的一篇文章&#xff0c;链接: 文件的编译链接 想要清楚为什么C语言不支持函数重载而C支持&#xff0c;有俩个过程…

大数据学习问题记录

问题记录 node1突然无法连接finalshell node1突然无法连接finalshell 今天我打开虚拟机和finalshell的时候&#xff0c;发现我的node1连接不上finalshell,但是node2、node3依旧可以链接&#xff0c;我在网上找了很多方法&#xff0c;但是是关于全部虚拟机连接不上finalshell&a…

12 - 常用类

那就别跟他们比&#xff0c;先跟自己比&#xff0c;争取今天比昨天强一些&#xff0c;明天比今天强一些。 1.包装类 针对八种基本数据类型封装的相应的引用类型。 有了类的特点&#xff0c;就可以调用类中的方法。&#xff08;为什么要封装&#xff09; 基本数据类型包装类b…

目标检测数据集 - 打架检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;打架检测数据集&#xff0c;真实监控场景高质量打架图片数据&#xff0c;涉及场景丰富&#xff0c;比如街道场景打架数据、酒吧场景打架数据、商店场景打架数据、公交车场景打架数据、监狱场景打架数据、空旷地打架数据、两人打架数据、多人群殴数据等。…

mysql中optimizer trace的作用

大家好。对于MySQL 5.6以及之前的版本来说&#xff0c;查询优化器就像是一个黑盒子一样&#xff0c;我们只能通过EXPLAIN语句查看到最后 优化器决定使用的执行计划&#xff0c;却无法知道它为什么做这个决策。于是在MySQL5.6以及之后的版本中&#xff0c;MySQL新增了一个optimi…

【Python】 将日期转换为 datetime 对象在 Python 中

基本原理 在 Python 中&#xff0c;处理日期和时间的库是 datetime&#xff0c;它提供了广泛的功能来处理日期和时间。datetime 模块中有一个 datetime 类&#xff0c;它可以用来表示日期和时间。有时&#xff0c;我们可能会遇到需要将日期字符串转换为 datetime 对象的情况&a…

计算机网络学习记录 运输层 Day5

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我…

Cocos入门2:软件安装

Cocos Creator的安装教程如下&#xff0c;按照步骤进行&#xff0c;可以帮助您顺利安装Cocos Creator&#xff1a; 一、下载Cocos Dashboard 访问Cocos官网&#xff1a;前往Cocos Creator的官方网站&#xff08;https://www.cocos.com/creator/&#xff09;。 下载Cocos Dash…

第二证券:创新高!2只北交所股票走势耀眼,活跃游资现身“龙虎榜”

尽管今日北交所商场保持震动的走势&#xff0c;北证50指数一度绿盘&#xff0c;不过一些个股走势却适当耀眼。 今日北证50指数全天收涨0.13%&#xff0c;122只个股飘红。个股方面&#xff0c;亿能电力低开高走&#xff0c;尤其是午后走势弱小&#xff0c;盘中狂飙一度大涨近28…

玩转Matlab-Simscape(初级)- 09 - 在Simulink中创建曲柄滑块机构的控制模型

** 玩转Matlab-Simscape&#xff08;初级&#xff09;- 09 - 在Simulink中创建曲柄滑块机构的控制模型 ** 目录 玩转Matlab-Simscape&#xff08;初级&#xff09;- 09 - 在Simulink中创建曲柄滑块机构的控制模型 前言一、问题描述二、创建模型2.1 识别机构中的刚体2.2 确定刚…

从当当网批量获取图书信息

爬取当当网图书数据并保存到本地&#xff0c;使用request、lxml的etree模块、pandas保存数据为excel到本地。 爬取网页的url为&#xff1a; http://search.dangdang.com/?key{}&actinput&page_index{} 其中key为搜索关键字&#xff0c;page_index为页码。 爬取的数据…

Java如何实现pdf转base64以及怎么反转?

问题需求 今天在做发送邮件功能的时候&#xff0c;发现邮件的附件部分&#xff0c;比如pdf文档&#xff0c;要求先把pdf转为base64&#xff0c;邮件才会发送。那接下来就先看看Java 如何把 pdf文档转为base64。 两种方式&#xff0c;一种是通过插件 jar 包的方式引入&#xf…

【5】MySQL数据库备份-XtraBackup - 全量备份

MySQL数据库备份-XtraBackup-全量备份 前言环境版本 安装部署下载RPM 包二进制包 安装卸载 场景分析全量备份 | 恢复备份恢复综合 增量备份 | 恢复部分备份 | 恢复 前言 关于数据库备份的一些常见术语、工具等&#xff0c;可见《MySQL数据库-备份》章节&#xff0c;当前不再重…

618超值推荐:年度必备好物清单,性价比数码好物一网打尽!

在这个信息爆炸、科技日新月异的时代&#xff0c;数码产品已经成为我们生活中不可或缺的一部分。它们不仅极大地丰富了我们的娱乐生活&#xff0c;也极大地提高了我们的工作效率和生活质量。然而&#xff0c;面对市场上琳琅满目的数码产品&#xff0c;如何在618购物节中做出最明…

用开源模型MusicGen制作六一儿童节专属音乐

使用的是开源模型MusicGen&#xff0c;它可以根据文字描述或者已有旋律生成高质量的音乐(32kHz)&#xff0c;其原理是通过生成Encodec token然后再解码为音频&#xff0c;模型利用EnCodec神经音频编解码器来从原始波形中学习离散音频token。EnCodec将音频信号映射到一个或多个并…

【EFK日志系统】docker一键部署kibana、es-head

docker一键部署kibana、es-head kibana部署es-head部署 上一篇文章搭建了es集群 规划服务器是 es01:172.23.165.185 es02:172.23.165.186 es03:172.23.165.187 那么kibana就搭建在主节点es01:172.23.165.185 按照顺序参考&#xff1a; docker一键部署EFK系统&#xff08;elas…

1.2 QT随手简记(二)

QT学习篇2 一、QT学习方法 1. QT查询与学习资源 QT助手&#xff1a;学会使用QT的助手和上网查询&#xff0c;掌握API文档的查询与使用。QT设计师界面&#xff1a;通过图形界面进行组件的拖拽布局&#xff0c;所见即所得。 2. QT设计师界面操作 跳转与代码生成&#xff1a;…

数据结构:模拟队列

数据结构&#xff1a;模拟队列 题目描述参考代码 题目描述 输入样例 10 push 6 empty query pop empty push 3 push 4 pop query push 6输出样例 NO 6 YES 4参考代码 #include <iostream>using namespace std;const int N 100010;int q[N], hh, tt;int m, x; string …

产品经理用AI,跟普通人有什么不同?

最近跟一个产品经理朋友聊天&#xff0c;他们公司最近单独拉一个只有产品经理的 team&#xff0c;要在接下来半年把过去几年火过的产品工具&#xff0c;“加上 AI 驱动”重新做一遍。 美其名曰“抓住 AI 浪潮的红利”。 这不是今天的重点&#xff0c;重点是他在高频的用 AI 设…