数据结构与算法简记--多模式字符串匹配AC自动机

AC自动机



一样的不太好理解,有时间再啃

敏感词过滤

单模式字符串匹配算法:(BF,RK,BM,KMP)每次取敏感词字典中一个敏感语做为模式串在用户输入的主串中进行匹配,效率较低

多模式字符串匹配算法:(Trie树,AC自动机)

Trie树:把用户输入的内容作为主串,从第一个字符(假设是字符 C)开始,在 Trie 树中匹配。当匹配到 Trie 树的叶子节点,或者中途遇到不匹配字符的时候,我们将主串的开始匹配位置后移一位,也就是从字符 C 的下一个字符开始,重新在 Trie 树中匹配。

Trie 树的这种处理方法,有点类似单模式串匹配的 BF 算法。我们知道,单模式串匹配算法中,KMP 算法对 BF 算法进行改进,引入了 next 数组,让匹配失败时,尽可能将模式串往后多滑动几位。

借鉴单模式串的优化改进方法,能否对多模式串 Trie 树进行改进,进一步提高 Trie 树的效率呢?这就要用到 AC 自动机算法了。

经典的多模式串匹配算法:AC 自动机

Trie 树跟 AC 自动机之间的关系,就像单串匹配中朴素的串匹配算法,跟 KMP 算法之间的关系一样,只不过前者针对的是多模式串而已。所以,AC 自动机实际上就是在 Trie 树之上,加了类似 KMP 的 next 数组,只不过此处的 next 数组是构建在树上罢了

各字符串匹配算法总结:

一、单模式串匹配:
1. BF: 简单场景,主串和模式串都不太长, O(m*n)
2. RK:字符集范围不要太大且模式串不要太长, 否则hash值可能冲突,O(n)
3. BM:模式串最好不要太长(因为预处理较重),比如IDE编辑器里的查找场景; 预处理O(m*m), 匹配O(n), 实现较复杂,需要较多额外空间.
4. KMP:适合所有场景,整体实现起来也比BM简单,O(n+m),仅需一个next数组的O(n)额外空间;但统计意义下似乎BM更快,原因不明.
5. 另外查资料的时候还看到一种比BM/KMP更快,且实现+理解起来都更容易的的Sunday算法,有兴趣的可以看这里:
http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/sundayen.htm
https://www.jianshu.com/p/2e6eb7386cd3

二、多模式串匹配:
1. Trie: 适合多模式串公共前缀较多的匹配(O(n*k)) 或者 根据公共前缀进行查找(O(k))的场景,比如搜索框的自动补全提示.
2. AC自动机: 适合大量文本中多模式串的精确匹配查找, 可以到O(n).

原文地址:https://www.cnblogs.com/wod-Y/p/12180685.html

时间: 2024-10-07 05:31:57

数据结构与算法简记--多模式字符串匹配AC自动机的相关文章

UVA 11019 Matrix Matcher 二维的字符串匹配 ac自动机

只要把每行的模版串插到ac自动机,然后匹配行,每次匹配成功,那一行对应的字符矩阵的左上角的计数器+1,最后统计下计数器矩阵有多少个左上角是行数的就可以了. 思路很简单,但想法很好,但要注意模版上有两行是一样的,插入到ac自动机的时候会插到同一个结点上,为了区分,我还是谨慎地开了个vector,然后1A了. #include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,s

模式字符串匹配问题(KMP算法)

这两天又看了一遍<算法导论>上面的字符串匹配那一节,下面是实现的几个程序,可能有错误,仅供参考和交流. 关于详细的讲解,网上有很多,大多数算法及数据结构书中都应该有涉及,由于时间限制,在这就不重复了. 需要说明的是: stra:主串,及需要从中寻找模式串的字符串 strb:模式串 <算法导论>上面包括严蔚敏老师<数据结构>,字符串下表是按从1开始,并且<数据结构>一书中貌似吧字符串的第一个字符用来储存字符串长度.这里我改成了0. maxlen :字符串的最长

算法系列笔记9(字符串匹配)

字符串匹配指有一个文本串S和一个模式串P,现在要查找P在S中的位置. 主要有以下算法: 其中朴素算法和KMP算法我们在这边bloghttp://blog.csdn.net/lu597203933/article/details/41124815中已经讲解过.RP算法时间复杂度较高,我也没看,想看可以看算法导论.这里主要讲解有限自动机的字符串匹配算法. 有限自动机的定义: 有限自动机字符串匹配主要是构建一个状态转移函数.&(q,a)表示状态q<其中状态q表示已经匹配成功q个字符了>接收字

算法学习-KMP(字符串匹配)解释

KMP算法 BF算法 BF算法就是我们最基本的求解字符串匹配的算法,算法的时间复杂度为O(M*N),空间复杂度为O(1),具体过程如下: 串 第一次 第二次 第三次 第四次 模式串S[i] abcababc abcababc abcababc abcababc 匹配串T[j] ababc ababc ababc ababc 可以看到在第三次匹配失败的时候,我们要回溯,直接S串直接i+=1,然后T串j=0从头继续开始.这样复杂度就比较高了. KMP算法 而KMP算法就是为了解决BF算法的复杂度比

数据结构与算法简记--剖析微服务接口鉴权限流背后的数据结构和算法

微服务鉴权限流剖析 微服务 把复杂的大应用,解耦拆分成几个小的应用. 有利于团队组织架构的拆分,毕竟团队越大协作的难度越大: 每个应用都可以独立运维,独立扩容,独立上线,各个应用之间互不影响. 有利就有弊: 大应用拆分成微服务之后,服务之间的调用关系变得更复杂,平台的整体复杂熵升高,出错的概率.debug 问题的难度都高了好几个数量级. 为了解决这些问题,服务治理便成了微服务的一个技术重点. 服务治理 简单点讲,就是管理微服务,保证平台整体正常.平稳地运行. 涉及的内容:鉴权.限流.降级.熔断.

笔试算法题(45):AC自动机(Aho-Corasick Automation)

议题:AC自动机(Aho-Corasick Automation) 分析: 此算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一:一个常见的例子就是给定N个单词,给定包含M个字符的文章,要求确定多少个给定的单词在文章中出现过:AC自动机在匹配文本时不需要回溯,处理时间复杂度与pattern无关,仅是target的长度O(N):构建AC自动机的时间复杂度: 与KMP算法类似,AC自动机也是利用前一个匹配模式串失效之后得到的信息来确定下一个匹配的开始位置,从而避免回移主串的匹配指针:与KM

Aho-Corasick 多模式匹配算法、AC自动机详解

Aho-Corasick算法是多模式匹配中的经典算法,目前在实际应用中较多. Aho-Corasick算法对应的数据结构是Aho-Corasick自动机,简称AC自动机. 搞编程的一般都应该知道自动机FA吧,具体细分为:确定性有限状态自动机(DFA)和非确定性有限状态自动机NFA.普通的自动机不能进行多模式匹配,AC自动机增加了失败转移,转移到已经输入成功的文本的后缀,来实现. 1.多模式匹配 多模式匹配就是有多个模式串P1,P2,P3...,Pm,求出所有这些模式串在连续文本T1....n中的

数据结构与算法简记--字符串匹配KMP算法

KMP算法 比较难理解,准备有时间专门啃一下. 核心思想与BM算法一样:假设主串是 a,模式串是 b.在模式串与主串匹配的过程中,当遇到不可匹配的字符的时候,我们希望找到一些规律,可以将模式串往后多滑动几位,跳过那些肯定不会匹配的情况. 不同的是:在模式串和主串匹配的过程中,把不能匹配的那个字符仍然叫作坏字符,把已经匹配的那段字符串叫作好前缀. 关键找相等的最长匹配前缀和最长匹配后缀.有两种情况,(1)如果b[i-1]的最长前缀下一个字符与b[i]相等,则next[i]=next[i-1]+1.

数据结构与算法简记--贪心算法

贪心算法 贪心算法问题解决步骤 第一步,当我们看到这类问题的时候,首先要联想到贪心算法:针对一组数据,我们定义了限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期望值最大. 第二步,我们尝试看下这个问题是否可以用贪心算法解决:每次选择当前情况下,在对限制值同等贡献量的情况下,对期望值贡献最大的数据. 第三步,我们举几个例子看下贪心算法产生的结果是否是最优的. 贪心算法实战分析 分糖果:有 m 个糖果和 n 个孩子.要把糖果分给这些孩子吃,但是糖果少,孩子多(m<n),所以糖果只能分配