当前位置: 首页 > news >正文

AC自动机-1

        AC自动机(Aho-Corasick Automaton)是一种高效的多模式字符串匹配算法。它是由Alfred Aho和Margaret Corasick在1975年提出的。这种算法可以在一次扫描输入文本的情况下,同时查找多个模式串

基本概念

  1. Trie树

    1. AC自动机是基于字典树数据结构构建的
    2. 字典树可以高效地存储和检索多个模式串
  2. Fail指针(失败指针)

    • 为了加速模式匹配的过程,AC自动机引入了fail指针的概念。
    • Fail指针连接着Trie树中的各个节点,当匹配过程中发生失配时,fail指针可以帮助我们快速跳转到下一个可能匹配的位置。
    • 每个节点的fail指针指向的是当前节点所表示的字符串最长后缀匹配的节点

构造过程

  • 首先根据多个模式串(待查询子串)构建Trie树。
  • 然后通过广度优先搜索(BFS)的方法为Trie树中的每个节点添加fail指针。
  • 最后,使用构建好的AC自动机在文本中查找所有的模式串。

        Trie树的构造比较简单,在此不再赘述。fail指针的构造和KMP算法中next数组的构建有些相似,但也有不同点:

  1. 共同点:两者同样是在失配的时候用于跳转的指针。
  2. 不同点:next 数组求的是最长的相同前后缀,而 fail 指针指向所有模式串的前缀中匹配当前状态的最长后缀

fail指针的构造过程如下:

        考虑字典树中当前的结点 u , u 的父结点是 p , p 通过字符 c 的边指向 u,即 \text{trans}(p,c) = u。假设深度小于 u 的所有结点的 fail 指针都已求得。

  1. 如果 \text{trans}(\text{fail}[p],c) 存在:则让 u 的 fail 指针指向 \text{trans}(\text{fail}[p],c) 。相当于在 p\text{fail}[p] 后面加一个字符 c,分别对应 u 和 \text{fail}[u]
  2. 如果 \text{trans}(\text{fail}[p],c) 不存在:那么我们继续找到 \text{trans}(\text{fail}[\text{fail}[p]],c)。重复 1 的判断过程,一直跳 fail 指针直到根结点。
  3. 如果依然不存在,就让 fail 指针指向根结点。

如此即完成了 \text{fail}[u]的构建。

图解示例:

下面是字符串 i、 he、 his、 she、 hers 组成的Trie树和fail指针。

 

匹配过程

  • 当文本中的字符与当前节点匹配时,就沿着子节点继续向下匹配。
  • 如果失配,就根据fail指针回退到下一个可能的匹配位置。
  • 这个过程会一直持续到找到所有的匹配位置或者遍历完整个文本。

代码示例


import java.util.*;public class ACAutomaton2 {private final ACNode root;public ACAutomaton2() {root = new ACNode();}// AC自动机的节点private static class ACNode {ACNode[] children = new ACNode[26]; // 假设只有小写字母ACNode fail; // 失败指针boolean isEndOfWord; // 标记是否为单词的结尾int length; // 如果是单词结尾,则记录单词长度}// 将模式串插入到Trie树中public void insert(String word) {ACNode node = root;for (char ch : word.toCharArray()) {int index = ch - 'a';if (node.children[index] == null) {node.children[index] = new ACNode();}node = node.children[index];}node.isEndOfWord = true;node.length = word.length();}// 构建失败指针public void buildFailurePointers() {Queue<ACNode> queue = new LinkedList<>();root.fail = null;queue.add(root);// 广度优先遍历while (!queue.isEmpty()) {ACNode current = queue.remove();for (int i = 0; i < 26; i++) {ACNode child = current.children[i];if (child != null) {if (current == root) {child.fail = root;} else {ACNode fail = current.fail;while (fail != null) {ACNode failChild = fail.children[i];if (failChild != null) {child.fail = failChild;break;}fail = fail.fail;}if (fail == null) {child.fail = root;}}queue.add(child);}}}}// 搜索文本中的所有模式串public List<Map.Entry<Integer, Integer>> search(String text) {List<Map.Entry<Integer, Integer>> resList = new LinkedList<>();ACNode node = root;for (int i = 0; i < text.length(); i++) {int index = text.charAt(i) - 'a';while (node != root && node.children[index] == null) {node = node.fail; // 失败指针发挥作用的地方}node = (node.children[index] != null) ? node.children[index] : root;ACNode temp = node;while (temp != root) {if (temp.isEndOfWord) {int startPos = i - temp.length + 1;int endPos = i + 1;// 与Java风格保持一致, end - start == length// System.out.println("Pattern found at index " + startPos + " to " + endPos);resList.add(new AbstractMap.SimpleEntry<>(startPos, endPos));}temp = temp.fail;}}return resList;}public static void main(String[] args) {ACAutomaton2 acAutomaton = new ACAutomaton2();acAutomaton.insert("he");acAutomaton.insert("she");acAutomaton.insert("hers");acAutomaton.insert("his");acAutomaton.buildFailurePointers();String longText = "ahishers";List<Map.Entry<Integer, Integer>> resList = acAutomaton.search(longText);System.out.println(resList);for (Map.Entry<Integer, Integer> e : resList) {System.out.println(longText.substring(e.getKey(), e.getValue()));}}
}

        理解下search过程中的内部while循环,需要从当前节点开始,遍历所有可能的路径(即沿着Fail指针回溯),检查是否有匹配的关键词。例如示例中,找到 she 之后,如果不回溯,则无法正确找到 he

思考

  • 多模式让你想到哪些应用场景?比如中文分词?
  • 在构建和查询时,fail指针存在多次跳转的问题,这种情况可不可以被优化呢?
  • AC自动机如何结合DoubleArrayTrie呢?

参考文档

https://zh.wikipedia.org/zh-hans/AC%E8%87%AA%E5%8A%A8%E6%9C%BA%E7%AE%97%E6%B3%95
AC 自动机 - OI Wiki
 

相关文章:

AC自动机-1

AC自动机&#xff08;Aho-Corasick Automaton&#xff09;是一种高效的多模式字符串匹配算法。它是由Alfred Aho和Margaret Corasick在1975年提出的。这种算法可以在一次扫描输入文本的情况下,同时查找多个模式串。 基本概念 Trie树 AC自动机是基于字典树数据结构构建的字典树…...

注解@Service@Component@Slf4j@Data

在Java中&#xff0c;这四个注解分别属于不同的用途和库&#xff0c;下面是它们各自的作用&#xff1a; Service&#xff1a; 这个注解通常用于Spring框架中&#xff0c;它用于标记服务层组件。在Spring中&#xff0c;服务层通常包含业务逻辑。当一个类被标记为Service&#xf…...

【Nodejs】六、express框架

目录 一、express 介绍 二、express 使用 2.1 express 下载 2.2 express 使用 三、express 路由 3.1 什么是路由 3.2 路由的使用 3.3 获取请求参数 3.4 获取路由参数 四、express 响应设置 五、express 中间件 5.1 什么是中间件 5.2 中间件的作用 5.3 中间件的类…...

进阶 pro max

最近搞了许多有趣的东西&#xff0c;比如自制rtos&#xff0c;速成数模电&#xff0c;学了一点点的AD&#xff0c;看着视频弄了HAL库&#xff0c;以及定时器和串口中断配合实现接收任意长度&#xff08;不超过缓冲值&#xff09;数据&#xff0c;还有配置hal库的freertosfafts …...

Agentic Security:一款针对LLM模型的模糊测试与安全检测工具

关于Agentic Security Agentic Security是一款针对LLM模型的模糊测试与安全检测工具&#xff0c;该工具可以帮助广大研究人员针对任意LLM执行全面的安全分析与测试。 请注意 Agentic Security 是作为安全扫描工具设计的&#xff0c;而不是万无一失的解决方案。它无法保证完全防…...

Spring Cloud Config 与 Spring Cloud Bus 来实现动态配置文件

要使用 Spring Cloud Config 与 Spring Cloud Bus 来实现动态配置文件&#xff0c;你可以按照以下步骤操作&#xff1a; ### 步骤 1: 添加依赖 首先&#xff0c;确保你的项目中添加了 Spring Cloud Config 客户端和 Bus 的依赖。对于 Maven 项目&#xff0c;pom.xml 文件应该…...

Qt:Qt背景

目录 1.Qt解释 2.Windows下开发GUI的方案 3.框架 4.Qt历史 4.Qt支持的平台 5.Qt版本 6.Qt案例 1.Qt解释 前端开发&#xff0c;分为网页前端开发&#xff08;Web)、桌面应用开发&#xff08;Windows、Linux&#xff09;、移动应用开发&#xff08;Android&#xff09;。Q…...

【数据结构】选择排序

&#x1f36c;个人主页&#xff1a;Yanni.— &#x1f308;数据结构&#xff1a;Data Structure.​​​​​​ &#x1f382;C语言笔记&#xff1a;C Language Notes &#x1f3c0;OJ题分享&#xff1a; Topic Sharing 目录 前言&#xff1a; 基本思想 直接选择排序 思路分…...

国产GD32单片机开发入门(二)GD32单片机详解

文章目录 一.概要二.单片机型号命名规则三.GD32F103系统架构四.GD32F103C8T6单片机启动流程五.GD32F103C8T6单片机主要外设资源六.单片机开发过程中查看芯片数据手册的必要性1.单片机外设资源情况2.GD32单片机内部框图3.GD32单片机管脚图4.GD32单片机每个管脚功能5.单片机功耗数…...

8个我平时每天都会看的网站,涵盖办公、娱乐、学习等

分享8个我平时每天都会看的网站&#xff0c;涵盖办公、娱乐、学习等多种类别&#xff0c;试过就知道有多好用&#xff01; 1、MyFreeMP3 tools.liumingye.cn/music/#/ 一个可以免费听歌的平台&#xff0c;不用充会员&#xff0c;里面收录了大多数的国内外知名流行歌手、乐队的…...

Vue2——父子之间间的调用

1、父组件给子组件传值使用props 父组件&#xff1a; <div><SonPage msg"通过props传递值---父>子" ></SonPage><h1>父组件</h1></div> 子组件 <div :style"{border: 1px solid red}"><h1>子组件…...

xfs Vs ext4?

xfs测试 ext4 测试 对比 XFS和EXT4都是Linux系统中广泛使用的文件系统&#xff0c;它们各有特点和优势&#xff0c;选择哪一个取决于你的具体需求和使用场景。下面是它们的主要特点&#xff1a; XFS: 由Silicon Graphics Inc.开发&#xff0c;最初用于SGI的IRIX系统。支持非…...

数据结构stack (笔记)

文章目录 1. 概念理解易混淆内容 2. 时间复杂度3. 实现方式4. 应用5. 内容出处 1. 概念理解 stack(中文名&#xff1a;堆栈、栈)&#xff1a;虽然它叫堆栈&#xff0c;但是它其实指的是栈&#xff0c;跟堆没啥关系。 栈的特性&#xff1a;先进后出、后进先出(这个过程就…...

SQL - 创建 表和数据库

创建和删除数据库 create database if not exists sql_store2; //创建 drop database if exists sql_store2; //删除 -- 创建数据库 create database if not exists sql_store2; drop database if exists sql_store2; 创建表 create table customers (someting); -- 创建表 cre…...

使用 Arch Linux 几个月有感 | 为什么我选择 Arch Linux ,Arch 的优缺点有什么 | 一些Linux发行版推荐

&#xff08;终端是 Yakuake &#xff0c;KDE 自带&#xff09; 一点碎碎念&#xff0c;可以跳过不看 几年前从 CentOS 接触的 Linux &#xff0c;试图搭建一个KMS服务器 但是失败了 &#xff0c;后来装过 Ubuntu Debian deepin Kali Kubuntu Manjaro&#xff0c;踩一路坑最后…...

SQLserver中的增删改查和数据类型

SQLserver增删查改语句 SQL Server 是一种关系数据库管理系统&#xff0c;用于存储、管理和检索数据。以下是一些基本的 SQL 语句&#xff0c;用于在 SQL Server 中执行增删查改操作&#xff1a; 插入数据&#xff08;Insert&#xff09; 插入完整行&#xff1a; INSERT INTO …...

个人收藏个性化、实用性、可玩性在线网站持续更新,与君共享

1.https://handraw.top/ 支持中文手绘效果的白板工具&#xff0c;比较怀旧复古风格 界面简单风 2.https://app.diagrams.net 流程图、UML图、网络图、组织结构图、思维导图等&#xff0c;比较专业 可导出图片 PDF HTLM等各种格式 3.https://www.processon.com 主要用于生成…...

win10蓝牙只能发送,无法接收

给win10升了级&#xff0c;到22H2&#xff0c;蓝牙出了问题 以前接收&#xff0c;就是默认直接就可以接收。现在只能发送&#xff0c;无法接收。 在网上找了很多办法都没奏效&#xff0c;目前的方法是&#xff0c; 每次接收&#xff0c;都要操作一次&#xff0c;而不是自动接…...

【论文阅读03】用于海洋物体检测的多注意力路径聚合网络

来源&#xff1a;用于海洋物体检测的多注意力路径聚合网络 |应用智能 (springer.com) 一、背景&#xff1a; 水下图像存在偏色、对比度低、能见度低等问题&#xff0c;使得海洋物体难以被探测到。这些都增加了海上目标探测的难度。 目前流行的检测器方法是基于卷积神经网络&…...

Linux 进程(2)

进程的回收 1.wait 原型 pid_t wait(int *status); 功能&#xff1a;该函数可以阻塞等待任意子进程退出 并回收该进程的状态。 一般用于父进程回收子进程状态。 参数&#xff1a;status 进程退出时候的状态 如果不关心其退出状态一般用NULL表示 如果要回收进程…...

[CSCCTF 2019 Qual]FlaskLight1

打开题目 右键查看一下源代码 看到提示&#xff0c;需要用GET方search函数...

layui table表单 checkbox选中一个其它也要选中

当我们选中其中一个商品的时候同类型的商品状态也要跟着改变 所以要在表单加载完成后去监听checkbox ,done:function (res) {console.log(详情表格数据,res)tableDetailList res.data;// 监听表格复选框选择table.on(checkbox( INST_SELECTORS.instLayFilters.unpaidTableDe…...

【pip镜像设置】pip使用清华镜像源安装

文章目录 问题&#xff1a;问题描述原因分析&#xff1a;PyPI&#xff08;Python Package Index&#xff09; PypI 镜像列表解决方案&#xff1a; 问题&#xff1a; 大家经常会使用 pip 进行python 的第三方库安装&#xff0c;但是&#xff0c;有时会出现 ERROR: Could not f…...

c++ 智能指针--std::shared_ptr

在C中&#xff0c;std::shared_ptr是智能指针的一种&#xff0c;它用于自动管理具有动态生命周期的对象。当std::shared_ptr的实例被销毁或重置时&#xff0c;它所指向的对象&#xff08;如果仍然存在&#xff09;将被自动删除&#xff08;调用delete&#xff09;&#xff0c;前…...

网络工程师学习笔记(二)

计算机网络概述——二 通信子网中转发节点的互联模式叫做子网的拓扑结构 常见的拓扑结构&#xff1a; 总线型(一条总干线上连接着多个终端) 特点&#xff1a;损坏一个节点会造成单点故障 星型&#xff08;中间一台服务器或者一各小型工作站周围都是计算机&#xff09; 特点…...

90.WEB渗透测试-信息收集-Google语法(4)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;89.WEB渗透测试-信息收集-Google语法&#xff08;3&#xff09; • inurl • 搜索特殊 UR…...

阿里Qwen2开源大模型本地部署及调试全攻略

阿里Qwen2开源大模型本地部署及调试全攻略 #Qwen2系列大模型性能卓越&#xff0c;超越业界知名模型。开源后受到AI开发者关注&#xff0c;支持多种语言&#xff0c;提升多语言理解。在预训练和微调上优化&#xff0c;实现智能水平提升。Qwen2系列模型在各项能力上均领先&#…...

『功能项目』移动后的光标显示【04】

我们打开上一篇03的射线双击项目&#xff0c; 本章要做的事情是在PlayerRayNavgation脚本中添加一个移动光标&#xff0c;实现人物在场景中鼠标点击移动后在移动过程中出现移动目标光标的效果。 在unity编辑器中创建一个Plane 重命名为MovementSign 删掉碰撞器 创建一个材质 选…...

HTML 基本语法特性与 title 标签介绍

目录 title标签 HTML 的基本语法特性 对换行和缩进不敏感 空白折叠现象 标签要严格封闭 title标签 在 HTML 中&#xff0c;<title>标签起着至关重要的作用&#xff0c;它主要用于定义文档的标题。通常情况下&#xff0c;<title>标签被放置在<head>标签内…...

CSS的:placeholder-shown伪类:精确控制输入框占位符样式

CSS&#xff08;层叠样式表&#xff09;是控制网页元素样式的强大工具。随着Web开发技术的进步&#xff0c;CSS不断引入新的选择器和伪类&#xff0c;以增强开发者对页面元素的控制能力。:placeholder-shown伪类是CSS中一个相对较新的特性&#xff0c;它允许开发者针对输入字段…...

网站建设需要什么流程/google ads 推广

转自&#xff1a;http://www.cnblogs.com/yangyh/archive/2011/06/04/2072393.html  首先这位作者&#xff0c; 因为看了这篇简短的一个博文&#xff0c; 我相同了关于虚函数方面的知识。 #include "stdafx.h" #include "stdio.h" #include "strin…...

网站建设公司现状/推广软件是什么工作

资源搜索Opencv249和Opencv3.0以上的 SolvePnp函数详解&#xff08;附带程序、算例&#xff09; cv2.solvepnp 相机的位姿估计 Opencv:SolvePNP关于OpenCV的那些事——相机姿态更新 公众号&#xff1a;计算机视觉与图形学实战...

网站如何做seo/app001推广平台

引言&#xff1a;最近在弄一个Vue的入门学习用项目&#xff0c;期间有用到 JavaScript 将中文转成拼音这个功能&#xff0c;这可真是为难人。想到了编码&#xff0c;但是没搞明白怎么将编码和拼音字母啥的联系起来。后来上网查询了才知道。声母韵母搭配的拼音&#xff08;早就忘…...

郑州建设网站/2023年新闻摘抄十条

今年清明节全国致敬英雄&#xff0c;为表示哀悼&#xff0c;很多网站的首页都变成了黑白的&#xff0c;这是怎么实现的呢&#xff1f;一般人都会想到给整个页面的所有内容逐一替换样式&#xff0c;将文字、图像和按钮都处理成灰色。但是工作量比较大&#xff0c;而且一旦有遗漏…...

农业部工程建设服务中心网站/百度搜索流量查询

A、 B 、 C 是 3 个字符串。把 A 中包含的所有 B 都替换为 C &#xff0c;如果替换以后还有 B 就继续替换&#xff0c;直到 A 不包含 B 为止。 1、请编写程序实现以上功能。不允许使用系统提供的字符串比较、查找和替换函数。 js版代码实现let a1 aaabbbcccbbbffbbb; let b1 …...

青岛正规的网站建设公司/seogw

原因很简单&#xff1a;win7,win8,WIN10自带了.net framework 4.6&#xff0c;版本比framework 4.5新了一点。而CAD2015的语言包(AutoCAD 2015 Language Pack)在安装中只能识别net framework 4.5&#xff0c;所以安装失败。CAD2015主程序没有问题&#xff0c;AutoCAD官方安装包…...