Aho-Corasick 算法 AC自动机实现
敏感词过滤在社区发帖、网站检索、短信发送等场景下是很常见的需求,尤其是在高并发场景下如何实现敏感词过滤,都对过滤算法提出了更高的性能要求,Ahocorasick算法能够实现毫秒级的万字过滤匹配,能够很好的满足各种场景下的敏感词过滤需求。
Aho-Corasick算法通过将模式串预处理为确定有限状态自动机,对待匹配文本扫描一遍就能完成匹配。算法复杂度为O(n),即与模式串的数量和长度无关。AC自动机是多模式匹配的一个经典数据结构,原理是和KMP一样的构造Fail指针,不过AC自动机是在Trie树上构造的,但原理是一样的。
多模式匹配:
多模式匹配就是有多个模式串P1,P2,P3…,Pm,求出所有这些模式串在连续文本T1…n中的所有可能出现的位置。
例如:求出模式集合 {“nihao”,“hao”,“hs”,“hsr”} 在给定文本 sdmfhsgnshejfgnihaofhsrnihao 中所有可能出现的位置。
想要了解Aho-Corasick算法,就首先要从字典树与DFA开始说起:
字典树(Trie)
https://www.cnblogs.com/vipsoft/p/17722820.html
字典树(Trie)是一种很特别的树状信息检索数据结构。利用字符串的公共前缀(common-prefix)来减少查询时间,搜索时间为O(d),d为树的深度。
字典树的原则:
- 根节点不含字符
- 根节点到某一终点连起来即为搜索字符串
- 任意节点的所有子节点包含字符不同

AC 算法思想
AC算法的主要思想就是构造的有限状态自动机,根据有限状态自动机会根据输入进行模式串匹配。有限状态自动机会随着字符的输入而发生状态转移,转移的状态有如下三种:
- success 状态,即AC自动机根据输入有能直接到达的状态;
- failure 状态,即AC自动机根据输入没有直接到达的状态,这时候就会发生跳转,跳转到其他一个路径;
- output 状态,即成功匹配到一个输入段;
示例讲解
以经典的ushers为例,模式串是he/ she/ his /hers 构建字典树,如图:(红色表示接受态)

文本为ushers , 构建的自动机如图(带虚线)
自动机从根节点0出发,首先尝试按success表转移
按照文本的指示转移,也就是接收一个u, 此时success表中并没有相应路线,转移失败,失败了则按照failure表回去。
按照文本指示,这次接收一个s,转移到状态3,成功了继续按success表转移,h到状态4,e到状态5
r失败由5跳转步骤2,或者遇到output表中标明的“可输出状态”(she)。此时输出匹配到的模式串,然后将此状态视作普通的状态继续转移。
算法高效之处在于,当自动机接受了“ushe”之后,再接受一个r会导致无法按照success表转移,此时自动机会聪明地按照failure表转移到2号状态,并经过几次转移后输出“hers”。来到2号状态的路不止一条,从根节点一路往下,“h→e”也可以到达。而这个“he”恰好是“ushe”的结尾,状态机就仿佛是压根就没失败过,也没有接受过中间的字符“us”,直接就从初始状态按照“he”的路径走过来一样。
功能解析
用 5 个模式串:"she","he","say","shr","her" 所建的字典树

通过分析可知,"she" 具有后缀字符串 "he","her" 具有前缀字符串,因此当 "she" 模式串发生失配的时候,就可以通过失配指针继续匹配 "her" 模式串,那么就需要将 "she" 中的 "h" 结点的失配指针指向 "her" 的 "h" 结点,将 "she" 中的 "e" 结点的失配指针指向 "her" 的 "e" 结点。至于其他的结点,由于不存在共有的前缀字符串和后缀字符串,因此它们的失配指针指向根结点。因此对于如图字典树,失配指针的关系如图所示:

通过分析可以得知,进行跳转的另一个模式串的结点深度一定小于跳转之前的结点的深度,这是因为若跳转后的结点深度大于原结点的深度,就无法保证跳转后模式串的前缀字符串与进行跳转的模式串的后缀字符串相匹配,这样结点数量完全不够。
例如上文的例子中,通过失配指针联系的 "she" 中的 "h" 结点和 "her" 的 "h" 结点(蓝色标出)中前者的层数大于后者, "she" 中的 "e" 结点和 "her" 的 "e" 结点(紫色标出)中前者的层数也大于后者:

根据这个特点,我们可以通过访问当前结点的双亲结点的方式进行试探,对于某一个字母结点(原字母),通过对其双亲的失配指针的访问,寻找到其他的结点,这个结点满足其孩子结点中存在与原字母相同的结点,此时就把原字母结点的失配指针指向寻找到的结点中与原字母相同的孩子结点。若访问到了根结点,没有发现符合要求的结点,则失配指针指向根结点。

代码示例(Python)
ahocorasick 目前改名为 pyahocorasick
https://pypi.tuna.tsinghua.edu.cn/simple/pyahocorasick/
#安装 ahocorasick 库
pip install pyahocorasick==1.4.4 -i https://pypi.tuna.tsinghua.edu.cn/simple
# coding:utf-8
import ahocorasick
def make_AC(AC, word_set):
for word in word_set:
AC.add_word(word, word) # 向trie树中添加单词
return AC
def ac_demo():
'''
ahocosick:自动机的意思
可实现自动批量匹配字符串的作用,即可一次返回该条字符串中命中的所有关键词
'''
key_list = ["胀痛", "看东西有时候清楚有时候不清楚", "畏光"]
AC_KEY = ahocorasick.Automaton()
AC_KEY = make_AC(AC_KEY, set(key_list))
AC_KEY.make_automaton()
test_str_list = ["请问最近看东西有时候清楚有时候不清楚是怎么回事", "有时候眼睛胀痛,畏光"]
for content in test_str_list:
name_list = set()
for item in AC_KEY.iter(content): # 将AC_KEY中的每一项与content内容作对比,若匹配则返回
name_list.add(item[1])
name_list = list(name_list)
if len(name_list) > 0:
print("\n", content, "--->命中的关键词有:", "、".join(name_list))
if __name__ == "__main__":
ac_demo()
请问最近看东西有时候清楚有时候不清楚是怎么回事 --->命中的关键词有: 看东西有时候清楚有时候不清楚
有时候眼睛胀痛,畏光 --->命中的关键词有: 畏光、胀痛

源代码地址:https://gitee.com/VipSoft/VipQA
参考:
https://www.cnblogs.com/linfangnan/p/12651873.html
https://www.cnblogs.com/cmmdc/p/7337611.html
Aho-Corasick 算法 AC自动机实现的更多相关文章
- 浅谈算法——AC自动机
在学习AC自动机之前,你需要两个前置知识:Trie树,KMP 首先我们需要明白,AC自动机是干什么的(用来自动AC的) 大家都知道KMP算法是求单字符串对单字符串的匹配问题的,那么多字符在单字符上匹配 ...
- AC自动机——多模式串匹配的算法思想
标准KMP算法用于单一模式串的匹配,即在母串中寻求一个模式串的匹配,但是现在又存在这样的一个问题,如果同时给出多个模式串,要求找到这一系列模式串在母串存在的匹配个数,我们应该如何处理呢? 基于KMP算 ...
- (转)两种高效过滤敏感词算法--DFA算法和AC自动机算法
原文:https://blog.csdn.net/u013421629/article/details/83178970 一道bat面试题:快速替换10亿条标题中的5万个敏感词,有哪些解决思路? 有十 ...
- 多模字符串匹配算法-Aho–Corasick
背景 在做实际工作中,最简单也最常用的一种自然语言处理方法就是关键词匹配,例如我们要对n条文本进行过滤,那本身是一个过滤词表的,通常进行过滤的代码如下 for (String document : d ...
- 数据结构14——AC自动机
一.相关介绍 知识要求 字典树Trie KMP算法 AC自动机 多模式串的字符匹配算法(KMP是单模式串的字符匹配算法) 单模式串问题&多模式串问题 单模就是给你一个模式串,问你这个模式串是否 ...
- COGS 1913. AC自动机
★★ 输入文件:ACautomata.in 输出文件:ACautomata.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 对,这就是裸的AC自动机. 要求:在 ...
- AC自动机--summer-work之我连模板题都做不出
这章对现在的我来说有点难,要是不写点东西,三天后怕是就一无所有了. 但写这个没有营养的blog的目的真的不是做题或提升,只是学习学习代码和理解一些概念. 现在对AC自动机的理解还十分浅薄,这里先贴上目 ...
- AC自动机-算法详解
What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...
- AC自动机算法详解
首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...
- 经典算法题每日演练——第八题 AC自动机
原文:经典算法题每日演练--第八题 AC自动机 上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题. 当然你也可以用KMP算法求出,那 ...
随机推荐
- c# 如何将枚举以下拉数据源的形式返回给前端
前言: 相信各位有碰到过与我类似的问题,当表中存一些状态的字段,无非以下几种形式1.直接写死 如: 正常:1,异常:2 ,还有一种则是写在字典中,再或者就是加在枚举上,前两者对于返回下拉数据源来说比较 ...
- TIM-BLDC六步换相-串口中断模拟检测霍尔信号换相-软件COM事件解析
TIM-BLDC六步换相-串口中断模拟检测霍尔信号换相-软件COM事件解析 一.COM事件解析 COM事件简介:COM事件即换相事件只用于高级定时器当中,其主要目的是用在BLDC方波的控制中,用于同时 ...
- [ARM 汇编]进阶篇—异常处理与中断—2.4.2 ARM处理器的异常向量表
异常向量表简介 在ARM架构中,异常向量表是一组固定位置的内存地址,它们包含了处理器在遇到异常时需要跳转到的处理程序的入口地址.每个异常类型都有一个对应的向量地址.当异常发生时,处理器会自动跳转到对应 ...
- 【技术积累】Git中的基础知识【一】
Git是什么?有什么特点? Git是一个分布式版本控制系统,常用于软件开发中的源代码管理.它最初由Linux开发者Linus Torvalds创建,旨在管理Linux内核的开发. Git具有以下特点: ...
- 盘点!国内隐私计算学者在 USENIX Security 2023 顶会上的成果
USENIX Security 是国际公认的网络安全与隐私计算领域的四大顶级学术会议之一.CCF(中国计算机学会) 推荐的 A 类会议. 每年的 USENIX Security 研讨会都会汇集大量研究 ...
- Java使用qq邮箱发送邮件(可做验证码使用)
pom.xml中导入发邮件需要的jar包 <!-- 邮箱 --> <dependency> <groupId>javax.mail</groupId> ...
- modulemap的使用方法
modulemap的作用 modulemap 文件是用来解决 C,Object-C,C++ 代码在 Swift 项目中集成的问题的. 在 Swift 项目中,如果需要使用 C,Object-C 或 ...
- Linux 命令:time
参考链接: time 命令
- 剪切图片, 原文自https://blog.csdn.net/sinat_41104353/article/details/85209456
因为在 OpenCV2 里面,所有的东西都是 numpy array 即 np.ndarray1,所以使用 opencv 剪切图像主要原理是用 ndarray 的切片.一张图片基本上都是三维数组:行, ...
- 构建易于运维的 AI 训练平台:存储选型与最佳实践
伴随着公司业务的发展,数据量持续增长,存储平台面临新的挑战:大图片的高吞吐.超分辨率场景下数千万小文件的 IOPS 问题.运维复杂等问题.除了这些技术难题,我们基础团队的人员也比较紧张,负责存储层运维 ...