Aho-Corasick 算法 AC自动机实现

简介: 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为树的深度。

字典树的原则:

  • 根节点不含字符
  • 根节点到某一终点连起来即为搜索字符串
  • 任意节点的所有子节点包含字符不同

双数组Trie树 (Double-array Trie)

https://www.cnblogs.com/vipsoft/p/17759850.html

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/vipsoft/p/17728136.html#构建-trie-字典树

参考:

https://www.cnblogs.com/linfangnan/p/12651873.html

https://www.cnblogs.com/cmmdc/p/7337611.html

目录
相关文章
|
4月前
|
存储 算法
HanLP — Aho-Corasick DoubleArrayTire 算法 ACDAT - 基于双数组字典树的AC自动机
HanLP — Aho-Corasick DoubleArrayTire 算法 ACDAT - 基于双数组字典树的AC自动机
60 0
|
算法
经典算法题每日演练——第八题 AC自动机
原文:经典算法题每日演练——第八题 AC自动机        上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题。 当然你也可以用KMP算法求出,那么它的时间复杂度为O(c*(m+n)),c:为模式串的个数。
935 0
|
算法
Aho-Corasick 多模式匹配算法、AC自动机详解
Aho-Corasick算法是多模式匹配中的经典算法,目前在实际应用中较多。 Aho-Corasick算法对应的数据结构是Aho-Corasick自动机,简称AC自动机。 搞编程的一般都应该知道自动机FA吧,具体细分为:确定性有限状态自动机(DFA)和非确定性有限状态自动机NFA。
956 0
|
16天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
22天前
|
机器学习/深度学习 算法 Serverless
基于WOA-SVM的乳腺癌数据分类识别算法matlab仿真,对比BP神经网络和SVM
本项目利用鲸鱼优化算法(WOA)优化支持向量机(SVM)参数,针对乳腺癌早期诊断问题,通过MATLAB 2022a实现。核心代码包括参数初始化、目标函数计算、位置更新等步骤,并附有详细中文注释及操作视频。实验结果显示,WOA-SVM在提高分类精度和泛化能力方面表现出色,为乳腺癌的早期诊断提供了有效的技术支持。
|
2天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。
|
10天前
|
存储 算法
基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真
本项目基于HMM模型实现金融数据预测,包括模型训练与预测两部分。在MATLAB2022A上运行,通过计算状态转移和观测概率预测未来值,并绘制了预测值、真实值及预测误差的对比图。HMM模型适用于金融市场的时间序列分析,能够有效捕捉隐藏状态及其转换规律,为金融预测提供有力工具。
|
18天前
|
算法
基于GA遗传算法的PID控制器参数优化matlab建模与仿真
本项目基于遗传算法(GA)优化PID控制器参数,通过空间状态方程构建控制对象,自定义GA的选择、交叉、变异过程,以提高PID控制性能。与使用通用GA工具箱相比,此方法更灵活、针对性强。MATLAB2022A环境下测试,展示了GA优化前后PID控制效果的显著差异。核心代码实现了遗传算法的迭代优化过程,最终通过适应度函数评估并选择了最优PID参数,显著提升了系统响应速度和稳定性。
下一篇
DataWorks