AC_BM算法的实现

本文详细介绍了AC_BM算法在内容过滤中的实现过程,包括算法原理、状态转移函数、匹配失败函数和输出函数的构建,以及如何在模式匹配自动机上进行操作。此外,还讨论了AC_BM算法与相似算法的区别,并提供了AC_BM在内容过滤场景下的具体应用,涉及树结构的构建、关键字的增删和匹配操作。
摘要由CSDN通过智能技术生成
AC_BM算法在内容过滤中的实现
1.另一个相似算法的介绍 http://www.win.tue.nl/~watson/2R080/opdracht/p333-aho-corasick.pdf
2.AC_BM的实现(为我的设计和总结) 4
3.ac_bm 在内容过滤中的应用... 7
AC_BM算法在模式匹配中的实现
在了解AC_BM实现之前,请参阅纪烨的<关于多模式字符串匹配的研究和实现>。(见附录一)
由于只给出了AC_BM的工作过程与实现思路,而并没有相应的算法描述,所以只能由另一相似的算法改进成我们所需要的AC_BM算法。首先介绍一下这种与AC_BM相似的算法。
1.另一个相似算法的介绍
首先介绍一下在网上查找到的文章,名为:"Efficient String Matching:An Aid to Bibliographic Search"。其中介绍了一种类似AC_BM的算法,它也可以对多字符串进行匹配查找,只不过它是从待匹配串的左侧向右进行的。然后再对这个算法进行改动,以实现AC_BM算法。这篇文章原文是英文的,以下为我的翻译,也许会有表述不清的地方,请参阅原文。

Efficient String Matching:An Aid to Bibliographic Search
      设K = {Yl,Y2 . . . . . Yk}是一个字符串的集合,里面的每一个元素都是一个字符串,这里我们称之为关键字。设x是一个任意的字符串,称之为待匹配串。当前的目的是在x中查找所有存在于K中的关键字。

      首先,建立一个模式匹配自动机:

Fig. 1. Pattern matching machine.
(a) Goto function.


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

i            output ( i )
2          {he}
5          {she, he}
7          {his}
9          {hers}
(c) Output function.

图1(a)中是一个匹配的自动机,其描述了对关键字{"he","she","his","hers"}的匹配过程。
图1(b)中是f( )函数的输入、输出值(后面会介绍)。
图1(c)中是在结点i处,可以匹配到的关键字。

      状态0是起始状态。图1中的所示的状态有0,1,2,......9。goto函数g提供了一种映射:将当前状态及下一个输入的符号映射到一个新状态中或是映射为失败信号fail,如图1(a)所示。如在状态0中接收到字符'h',而进行状态1,可以表示为g(0, h) = 1。不存在的字符指向状态fail。因此,g(1,x )= f a i l,因为对于状态1来说,x既不是i也不是e。
              匹配失败的函数f( )给出了另一个映射,它用在goto函数指向fail的情况下。一个确定的状态说明有可能存在一组已经发生的匹配,output函数就指出了每一个状态中发生匹配的内容(可能为空)。

模式匹配自动机的操作循环定义如下:
1.  如果g ( s , a ) = s',自动机进行goto转换,将当前状态转换到s',而将x中的下一个字符看作是当前字符。另外,如果output(s')不为空,则自动机输出output(s')中的字符串,这个查找循环结束。
2.  如果g ( s , a ) = f a i l,则自动机就会参考函数f( )。如果f ( s ) = s',则自动机就将当前状态转到s',并将字符'a'做为当前字符。

算法1:在待匹配串x中查找关键字。
输入:待匹配串x, g ( ), f ( ), output ( )。
输出:关键字的位置。
begin
state ~ 0
for i ~ 1 until n do
begin
while g (state, a i ) = fail do state= f ( s t a t e )
state= g (state, ai )
if output (state) != empty then
begin
print I
print output (state)
end
end
end

构造g( ), f( ), output( )
先明确一个定义depth:某结点(状态)的depth就是这个结点到根结点的字符串的长度。如图1,状态0的depth为0;1和3的depth为1;2、4、6的depth为2等等。
      需要通过g( )来计算f( )。首先计算depth为1的状态的f ( )值,再计算depth为2的f( )值,依此类推。状态0没有f( )值,因为状态0对所有的字符a都存在有合法的g(0,a)值。
      为了计算depth为d的状态s的f()值,我们对每一个depth为d-1的状态r如下操作:
1.  如果g(r,a) = fail对每一个字符a都成立,则不进行操作,得到下一个r,重复1。
2.  如果存在一个a,使g(r,a) =s,进行如下操作,否则得到下一个r,重复1。
a)      设置state = f (r)。
b)      执行0次或多次state = f (state),直到g (state,a)!=fail。(因为g (0,a)!=fail,所以此条件总可以满足。
c)      f (s) = g (state,a)。
如:为了计算图1(a)中的f ( )值,我们可以首先设置f(1 ) = f ( 3 ) = 0 因为它们的depth为1。接下来可以计算depth为2的状态2、4、6的f ( ) 值。为了计算f ( 2 ) , 设state = f(1 ) = 0; 因为 g(0, e)= 0, 所以f ( 2 ) = 0. 为了计算 f ( 6 ) , 设state= f ( 1 ) = 0,因为 g(0, i) = 0,所以 f ( 6 )= 0。为了计算f ( 4 ) , 设state = f ( 3 ) = 0,因为 g(0, h) = 1, 所以f ( 4 ) = 1。用这种方法可以得到图1(b)中所示的f ( )值。
      计算g( ) , f( ) output( ) 的算法如下:

Algorithm 2. 构造g( )
输入: 一组关键字: K = {Yl, Y2 . . . . . Yk}.
输出:g()及不完整的 output( )
Method:假设在计算的开始时 output(s)为空,g ( s , a) = f a i l如果a或 g(s, a) 没有被定义。函数 enter(y)是将关键字y插入到goto树中。
begin
newstate .-- 0
for i = 1 until k do enter(y i )
for all asuch that g(O, a) = f a i l  d o  g(O, a) = 0
end

procedure enter(a 1 a 2 • • • a m ):
begin
state = 0; j = 1
while g (state, aj ) != f a i l do
begin
state = g (state, a) )
j=j +1
end
for p = j until m do
begin
newstate = newstate + 1
g (state, ap ) = newstate
state = newstate
end
output(state) ~ { a I a 2 . . . a m}
end

下面的算法是用来计算f( )及完整的output( )的。
Algorithm 3 构造f( ) 及完整的output( )
输入:g( )及由算法2构造的output()函数
输出:f( ) 及完整的output( )

begin
queue=empty
for each a such that (g(O, a ) = s) != 0 do
begin
queue 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值