AC算法初探

来源:互联网 发布:养生源码 编辑:程序博客网 时间:2024/06/10 13:05
AC算法初探
     一、什么是AC算法
AC算法,即Aho-Corasick自动机算法。 该算法一次遍历原串便可定位所有模式串在原串中出现的位置。该算法通过所有的模式串构建一个有限状态自动机,然后用这个自动机去处理原串(只要一次遍历即可);



二、AC算法流程
AC算法总共由三部分组成,分别是a)  Goto函数 b) Failure 函数  c) Output 函数

举个例子,设模式串组为{he, she, his, hers}  原串为“ushers”

下面直接给出Goto函数表、 Failure函数表以及Output函数表
a) Goto函数表



b)Failure函数表


     i   1   2   3  4  5  6  7  8  9
   f(i)  0  0   0  1  2  0  3  0  3 



c)Output函数表
i           output(i)
2              {he}
5          {she, he}
7             {his}
9             {hers}



下面开始匹配,原串"ushers"   
起始状态为0;g(s, a) == fail表示失配




伪代码:
设原串为a1a2...an
begin state <- 0for i <- 1 until n do beginwhile g(state, ai)==fail do state <- f(state)state <- g(state, ai)if output(state) != empty thenbeginprint iprint output(state)endendend




三、 Goto函数、 Failure函数以及Output函数的构造

a) Goto函数
/**     Goto 函数的构造 *  输入: 模式串组{y1, y2, ..., yk} *  输出: g函数 和  部分构造的output函数 *  方法: 当s赋初值时, output(s) == empty *         当a没有被定义,或是g(s, a)没有被定义时, g(s, a) == fail *    */  begin newstate <- 0for i <- 1 until k do entry(yi)/*  起始状态的fail都置0 */for all a (maybe a, b, c, ..., z)  such that g(0, a) == fail  do g(0, a) <- 0 end   procedure  enter(a1a2...am): beginstate <- 0; j <- 1while g(state, aj) != failbegin state <- g(state, aj)j <- j+1endfor p <- j until m dobeginnewstate <- newstate + 1g(state, ap) <- newstatestate <- newstateendoutput (state) <- {a1a2...am}end


b)  Failure函数构造  
/**   Failure函数构造   *输入: goto函数  以及  部分构造的output函数 *输出: failure函数  和   output函数 * **/ begin queue <- empty/* 第一层的failure函数值置0 */for each a such that g(0, a) == s !=0  dobeginqueue <- queue ∪ {s}f(s) <- 0endwhile queue != empty dobegin/* 从队列中取出一个元素r */let r be the next state  in queuequeue <-  queue - {r}for each a such that g(r, a) == s != fail do beginqueue <- queue ∪ {s}state <- f(r)while g(state, a) == fail  do state <- f(state)f(s) <- g(state, a)output(s) <- output(s) ∪ output (f(s))endendend

四、非确定有限状态自动机确定化
     在AC流程中,当g(r, a) == fail时, 可能需要查询多次Failure表,像这样的不确定给识别带来的反复,无疑会影响自动机工作的效率。

    
/**   构造确定有限状态自动机 *    输入:   goto函数 和 failure函数 *    输出:   下一步跳转函数δ函数 **/begin queue <- emptyfor each symbol a do begin δ(0, a) <- g(0, a)if g(0, a) != 0 then queue <- queue ∪ {g(0, a)}endwhile queue != empty dobegin let r be the next state in queuequeue <- queue - {r}for each symbol a doif g(r, a) ==s != fail dobegin queue <- queue ∪ {s}δ(r, a) <- sendelseδ(r, a) <- δ(f(r), a)endend





参考:《Efficient String Matching: An Aid to Bibliographic Search》
   



0 0