AC自动机-算法详解
What's Aho-Corasick automaton?
一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一。
简单的说,KMP用来在一篇文章中匹配一个模式串;但如果有多个模式串,需要在一篇文章中把出现过的模式串都匹配出来,就需要Aho-Corasick automaton算法了。
My Understanding About Aho-Corasick automaton
我的理解:Aho-Corasick automaton = Trie + KMP
在KMP算法中,匹配单个字符的时候,我们只需要按照文本线性的扫一遍,然后中途失配的时候,next数组会引导k回溯到正确的位置进行下一步的匹配。
但是多个模式串的时候要怎么匹配呢?Trie树不就是一个多模式的匹配吗,如果我们将KMP和Trie数结合起来,是不是会有意想不到的效果呢?
有了这些思考,AC自动机算法就这样产生了。
在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针,fail指针,顾名思义,就是当匹配失败的时候,用来引导k回溯的一个插穿在Trie树的各个节点之间的一些指针,就和KMP算法中的next数组是一样的道理。
关于fail指针的构建,推荐看一下李翔大神的PPT。
ppt下载链接:
http://wenku.baidu.com/view/93af2c936bec0975f465e2f1.html
1.构建Trie树

2.在Trie树上构建fail指针

构建完fail指针后,我们就用文章来对这棵Trie树进行匹配了。
匹配过程分两种情况:
- 当前字符匹配,表示从当前节点沿着树边有一条路径可以到达目标字符,此时只需沿该路径走向下一个节点继续匹配即可,目标字符串指针移向下个字符继续匹配;
- 当前字符不匹配,则去当前节点fail指针所指向的字符继续匹配,匹配过程随着指针指向root结束。重复这2个过程中,直到模式串走到结尾为止。
对照上图,看一下模式匹配这个详细的流程,其中模式串为yasherhs。
对于i=0,1。Trie中没有对应的路径,故不做任何操作;i=2,3,4时,指针p走到左下节点e。
因为节点e的count信息为1,所以cnt+1,并且讲节点e的count值设置为-1,表示改单词已经出现过了,防止重复计数,最后temp指向e节点的失败指针所指向的节点继续查找,以此类推,最后temp指向root,退出while循环,这个过程中count增加了2,表示找到了2个单词she和he。
当i=5时,程序进入第5行,p指向其失败指针的节点,也就是右边那个e节点,随后在第6行指向r节点,r节点的count值为1,从而count+1,循环直到temp指向root为止。
最后i=6,7时,找不到任何匹配,匹配过程结束。
匹配过程总结:
从root节点开始,每次根据读入的字符沿着自动机向下移动。
当读入的字符,在分支中不存在时,递归走Fail指针。如果走Fail指针走到了root节点,则跳过该字符,处理下一个字符。
因为AC自动机是沿着输入文本的最长后缀移动的,所以在读取完所有输入文本后,最后递归走Fail指针,直到到达根节点,这样可以检测出所有的模式。
这个过程和KMP算法的匹配也是非常相似,当然这一步就非常灵活了,我们需要通过多做题来提高熟练度。
Time Complexity Analyse
假设有N个模式串,平均长度为L;文章长度为M。
建立Trie树:O(N*L)
建立fail指针:O(N*L)
模式匹配:O(M*L) (注:之所以要乘以一个L,是因为在统计的时候需要顺着链回溯到root结点)
所以,总时间复杂度为:O( (N+M)*L )
Some Good Selection Of Standard Exercise
Entry:
- Hdu 2222
- Hdu 3695 Computer Virus on Planet Pandora
- Poj 4052 Hrinity (金华邀请赛I)
- Zoj 3430 Detect the Virus
- Spoj 7758. Growing Strings
- Hdu 4417 GRE Words
- Hnu 10104 病毒
- Hnu 11187 Emoticons :-)
- Zoj 3545 Rescue the Rabbit
- Hdu 3341 Lost's revenge
- Zoj 3535 Gao the String II
- Hdu 3962 Microgene
- 大视野 2434 阿狸的打字机
- Hdu 3247 Resource Archiver
- Zoj 3494 BCD Code
synthesize problems:
- TSP HDU 3341. Lost's revenge HDU 3247. Resource Archiver
- 状态压缩、可变进制编码 HOJ 2951. Writing Robot / HDU 3505
- 最大权闭合子图 ZeroJudge b179.Cans
- 自动机 DP、fail 指针转移 CodeChef July Challenge 2012. Favourite Numbers
- 二分答案、数位 DP、构造方案 Andrew Stankevich's Contest #2, Problem A, Non Absorbing DFA
- 预处理、DP、高精度 SPOJ. 9941. GRE Words / HDU 4117
AC自动机-算法详解的更多相关文章
- AC自动机算法详解
首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...
- AC自动机算法详解 (转载)
首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...
- 【转】AC算法详解
原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和 ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- [转] KMP算法详解
转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的K ...
- KMP算法详解(转自中学生OI写的。。ORZ!)
KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...
- 第二十九节,目标检测算法之R-CNN算法详解
Girshick, Ross, et al. “Rich feature hierarchies for accurate object detection and semantic segmenta ...
- kmp算法详解
转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...
- 机器学习经典算法详解及Python实现--基于SMO的SVM分类器
原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector ...
随机推荐
- android http 抓包
有时候想开发的时候想看APP发出的http请求和响应是什么,这就需要抓包了,这可以得到一些不为人知的api,比如还可以干些“坏事”... 需要工具: Fiddler2 抓包(点击下载) Android ...
- .NET Core的日志[2]:将日志输出到控制台
对于一个控制台应用,比如采用控制台应用作为宿主的ASP.NET Core应用,我们可以将记录的日志直接输出到控制台上.针对控制台的Logger是一个类型为ConsoleLogger的对象,Consol ...
- .net 大型分布式电子商务架构说明
.net大型分布式电子商务架构说明 背景 构建具备高可用,高扩展性,高性能,能承载高并发,大流量的分布式电子商务平台,支持用户,订单,采购,物流,配送,财务等多个项目的协作,便于后续运营报表,分析,便 ...
- Mysql命令大全
格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root -p,回车后提示你输 ...
- [开发笔记]GCC 分支预测优化
#define likely(x) __builtin_expect(!!(x),1)#define unlikely(x) __builtin_expect(!!(x),0) 用于优化在做分支判断的 ...
- APP多版本共存,服务端如何兼容?
做过APP产品的技术人员都知道,APP应用属于一种C/S架构的,所以在做多版本兼容,升级等处理则比较麻烦,不像web应用那么容易.下面将带大家分析几种常见的情况和应对方式: 小改动或者新加功能的 这种 ...
- ECharts数据图表系统? 5分钟上手!
目录: 前言 简介 方法一:模块化单文件引入(推荐) 方法二:标签式单文件引入 [前言] 最近在捣鼓各种插件各种框架,发现这个ECharts还是比较不错的,文档也挺全的,还是中文的,给大家推荐一下. ...
- 【一起学OpenFOAM】系列由来
1 为什么要学习OpenFOAM 掐指算起来,接触CFD也差不多有十个年头了,其间一直使用的商用CFD软件,有Fluent.CFX.StarCCM+等,这些商用软件各有其优缺点,都能较好的解决常规的工 ...
- python安装BeautifulSoup注意事项
好久没有写爬虫了,最近用Python的BeautifulSoup4.Scrapy分别对以前写的spider进行优化,发现python3.5后这些库变化了很多,遇到了许多问题,在这里做一下总结. 切换环 ...
- Quartz
Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中.它提供了巨大的灵 活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度. eg: ja ...