一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一。php
简单的说,KMP用来在一篇文章中匹配一个模式串;但若是有多个模式串,须要在一篇文章中把出现过的模式串都匹配出来,就须要Aho-Corasick automaton算法了。html
个人理解:Aho-Corasick automaton = Trie + KMP算法
在KMP算法中,匹配单个字符的时候,咱们只须要按照文本线性的扫一遍,而后中途失配的时候,next数组会引导k回溯到正确的位置进行下一步的匹配。数组
可是多个模式串的时候要怎么匹配呢?Trie树不就是一个多模式的匹配吗,若是咱们将KMP和Trie数结合起来,是否是会有意想不到的效果呢?ui
有了这些思考,AC自动机算法就这样产生了。编码
在AC自动机中,咱们首先将每个模式串插入到Trie树中去,创建一棵Trie树,而后构建fail指针,fail指针,顾名思义,就是当匹配失败的时候,用来引导k回溯的一个插穿在Trie树的各个节点之间的一些指针,就和KMP算法中的next数组是同样的道理。spa
关于fail指针的构建,推荐看一下李翔大神的PPT。3d
ppt下载连接:指针
http://wenku.baidu.com/view/93af2c936bec0975f465e2f1.htmlcode
1.构建Trie树
2.在Trie树上构建fail指针
构建完fail指针后,咱们就用文章来对这棵Trie树进行匹配了。
匹配过程分两种状况:
对照上图,看一下模式匹配这个详细的流程,其中模式串为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算法的匹配也是很是类似,固然这一步就很是灵活了,咱们须要经过多作题来提升熟练度。
假设有N个模式串,平均长度为L;文章长度为M。
创建Trie树:O(N*L)
创建fail指针:O(N*L)
模式匹配:O(M*L) (注:之因此要乘以一个L,是由于在统计的时候须要顺着链回溯到root结点)
因此,总时间复杂度为:O( (N+M)*L )
Entry:
synthesize problems: