zoukankan      html  css  js  c++  java
  • 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:

    synthesize problems:

  • 相关阅读:
    Java
    Java
    Python 浮点数类型的精度问题
    Ubuntu下pip的更新问题
    初章
    第二次结对编程作业
    第一次结对编程作业
    Shengnan的《构建之法》读书笔记
    Backend事后诸葛亮
    ASE Alpha Sprint
  • 原文地址:https://www.cnblogs.com/crazyacking/p/4002807.html
Copyright © 2011-2022 走看看