AC自动机——多模式串匹配的算法思想
标准KMP算法用于单一模式串的匹配,即在母串中寻求一个模式串的匹配,但是现在又存在这样的一个问题,如果同时给出多个模式串,要求找到这一系列模式串在母串存在的匹配个数,我们应该如何处理呢?
基于KMP算法,我们能够想到的一个朴素算法就是,枚举这多个模式串,然后进行多次KMP算法,这个过程中完成计数,假设这里有n个模式串,那么整个算法的复杂度大约是O(n*m),m是母串的长度,这里的时间复杂度是粗略估计,没有计算辅助数组的时间(KMP中的next数组),但是这种复杂度还是太高,没有做到KMP算法中“成分利用已知信息”的核心思想,这里有一个巧妙的算法——AC自动机,能够线性的完成多模式串的匹配,即时间复杂度能够优化到O(m)。
下面简单的介绍一下解决多模式串匹配问题的AC自动机算法的思想。
回想起KMP所呈现的思想,我们在匹配之前需要充分挖掘模式串中所蕴含的信息,我们通过求得模式串的next数组,使得我们在遍历母串的时候得到了极大的优化,那么这里对于多模式串的匹配,应该采取相同的思路,我们应该对多个模式串所蕴含的信息进行充分挖掘。
由多模式串朴素的二维数组的存储,为了节省空间,我们又会联想到之前的字典树,这里我们基于多个模式串,建立一个字典树,然后线性扫母串的时候,就是在这样一个字典树上扫。
再次回想KMP中匹配过程,求得next数组时候,我们在母串上移动模式串完成匹配,基于next数组,我们得到的优化使得在模式串匹配失败之后,能够极大限度的往母串的右侧移动同时能够保证不漏掉任何匹配情况。但是在AC自动机这里,做法上有点区别,但是思想是一致的。做法上的区别体现在,基于多模式串的字典树上,我们将母串在字典树上进行匹配,我们在构造字典树的时候,记录模式串的最后一个字符作为终止节点,那么母串在字典树上匹配到终止节点的时候,就表明完成了一个模式串的匹配。
那么现在我们需要完成的就是匹配失败后的优化,在母串区间str[i]~str[j]匹配失败以后,最优的做法应该是,求得str[i]~str[j]这段字符串最长的公共前缀和与后缀和,然后继续从这个最长的前缀和这条支路下,继续进行匹配。为了完成这一步“极大限度的往母串的右侧移动同时能够保证不漏掉任何匹配情况”,我们在字典树每个节点处设置一个“匹配失败跳转”指针(下文统称fail指针),记录如果在该点匹配失败,最优化的情况下我们应该跳转到的字典树的位置。
能够看到,整个AC自动机呈现的多模式串匹配其实和KMP算法是高度的相似的。
那么下面就需要解决的问题就是,就像计算KMP中的next数组,这里我们如何计算字典树里的fail指针。
假设我们当前在找vi的fail指针,那么很显然,我们去找vi的父节点的fail指针所指向的节点vp,根据该指针的定义,很容易看到:
(1) 如果当前节点vp的子节点vj能够与vi匹配,那么vi的fail指针必然指向vj。
(2) 如果当前节点vp的子节点没有能够与vi匹配的,那么我们需要去找vp的fail指针指向的节点的子节点,看是否有与vi相互匹配的,没有的话,循环操作。
对于(2)似乎形成了一个递归模式,为什么会这样呢?或者说这样做的正确性体现在哪里呢?它源于fail指针的定义,仔细的读者应该能够看到,fail指针本质上是一个描述一个字符串最长的公共前缀与后缀,对于一段字符串str[i]~str[j],失配之后我们在该段字符串最长公共前后缀(记作str[p]~str[j])的基础上,添加那个导致失配的字符a,但是字典树中可能不存在这种情况,难道我们就因此重新开始新的匹配么?当然不,我们再找一下字符串str[p]~str[j]的最长公共前后缀(记作str[k]~str[j]),添加那个导致失配的字符a,然后循环操作……
这就是解决AC自动机的一个简答的思想描述。
能够看到它与KMP算法思想同步到了一致,这启示我们学习过程中的触类旁通,这种现象在很多地方也有着很明显的体现(积分、二重积分、三重积分;一元函数、多元函数;单一变量分布、多变量联合分布)。很多思维思想在一维的角度建立,然后推广到二维角度甚至更高维度。
AC自动机——多模式串匹配的算法思想的更多相关文章
- AC 自动机——多模式串匹配
网站上的敏感词过滤是怎么实现的呢? 实际上,这些功能最基本的原理就是字符串匹配算法,也就是通过维护一个敏感词的字典,当用户输入一段文字内容后,通过字符串匹配算法来检查用户输入的内容是否包含敏感词. B ...
- AC自动机 - 多模式串匹配问题的基本运用 + 模板题 --- HDU 2222
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例
摘要: 本文主要讲述了AC自动机的基本思想和实现原理,如何构造AC自动机,着重讲解AC自动机在算法竞赛中的一些典型应用. 什么是AC自动机? 如何构造一个AC自动机? AC自动机在算法竞赛中的典型应用 ...
- AC自动机 - 多模式串的匹配运用 --- HDU 2896
病毒侵袭 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=2896 Mean: 略 analyse: AC自动机的运用,多模式串匹配. ...
- AC自动机 - 多模式串的匹配 --- HDU 3695 Computer Virus on Planet Pandora
Problem's Link Mean: 有n个模式串和一篇文章,统计有多少模式串在文章中出现(正反统计两次). analyse: 好久没写AC自动机了,回顾一下AC自动机的知识. 本题在构造文章的时 ...
- AC自动机 - 多模式串的匹配运用 --- HDU 3065
病毒侵袭持续中 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=3065 Mean: 略 analyse: AC自动机的运用. 这一题 ...
- (转)两种高效过滤敏感词算法--DFA算法和AC自动机算法
原文:https://blog.csdn.net/u013421629/article/details/83178970 一道bat面试题:快速替换10亿条标题中的5万个敏感词,有哪些解决思路? 有十 ...
- HDU 2222:Keywords Search(AC自动机模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2222 KMP是单模式串匹配的算法,而AC自动机是用于多模式串匹配的算法.主要由Trie和KMP的思想构成. 题意 ...
- AC自动机基础知识讲解
AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...
随机推荐
- acrobat GetSize 返回 x,y 值单位
GetSize:LPDISPATCH GetSize();Description:Gets a page’s width and height in points.Parameters:Return ...
- ios专题 -线程互斥与同步
[原创]http://www.cnblogs.com/luoguoqiang1985 今天遇见了这问题,决定要需要讨论下. 线程同步的方法: @synchronized 官方文档解释:The @syn ...
- Java中报错No enclosing instance of type caiquan is accessible. Must qualify the allocation with an enclosing instance of type caiquan (e.g. x.new A() where x is an instance of caiquan).
package test;import java.util.Scanner;import java.util.Random;public class caiquan { public static v ...
- 网络编程(学习整理)---3--(Udp)FeiQ实现广播消息群发
1.广播群发消息: 这里使用的任然是UDP协议,使用方法还是比较简单的! 我就记录一下需要注意的一些地方(笔记): (1)这里是在局域网内,借用FeiQ聊天软件,编写一段程序,实现对局域网内的每一个登 ...
- 生产者与消费者(二)---await与 signal
前面阐述了实现生产者与消费者问题的一种方式:wait() / notify()方法,本文继续阐述多线程的经典问题---生产者与消费者的第二种方式:await() / signal()方法. await ...
- 基础-函数3(IIFE立即执行函数)
参考链接: http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife http://segmentf ...
- 大数据技术人年度盛事! BDTC 2016将于12月8-10日在京举行
2016年12月8日-10日,由中国计算机学会(CCF)主办,CCF大数据专家委员会承办,中国科学院计算技术研究所和CSDN共同协办的2016中国大数据技术大会(Big Data Technology ...
- flash player over linux
flashplayer官方网址:https://get.adobe.com/cn/flashplayer/ flash插件安装方法一(适用于ubuntu等linux系统): ...
- python随机数
前提:需要导入random模块 >>>import random 1.random.random random.random()用于生成一个0到1的随机符小数: 0 <= n ...
- Hust 1231 Coin
题目链接 题意: 亮亮有N个有瑕疵的硬币,有瑕疵意味着抛一枚硬币正面向上的概率 不等于 反面向上的概率 也即概率不等于0.5. 现在亮亮一次抛N个硬币 , 恰好有K个硬币正面向上 ,接着他又想抛一次 ...