Wu-Manber字符串多模式匹配

Wu-Manber算法采用跳跃不可能匹配字符和hash散列的方法,加速匹配的进行。该方法需要对所有模式进行预处理,构建SHIFT,HASH和PREFIX这3个表。SHIFT表同Boyer-Moore算法里的转移表,用来存储字符集中所有块字符在文本中出现时的转移距离;HASH表用来存储匹配窗口内尾块字符散列值相同的模式串;PREFIX表用来存储匹配窗口内首块字符散列值相同的模式串。在对模式串进行匹配的时候就是利用这三个表完成文本的扫描和寻找匹配的过程。


首先介绍预处理过程:

1、计算模式集合P中最短的模式长度m。后续讨论仅考虑每个模式串的前m个字符(那剩余的怎么办呢?o还没想明白),设这些长度为m的模式串组成新集合P’。

2、对P’中每个模式串进行分块,以B个字符为块长度,每次比较长度为B的块。推荐取B=log|Σ|(2*m*k),其中k是模式串的个数,|Σ|是the size of alphabet。

3、构建一个SHIFT表,该表用于在扫描文本串时,根据读入的块决定移动的距离。对于|Σ|大小的字符集,长度为B的块的组合方式有|Σ|^B种可能,因此表的大小为|Σ|^B。

4、将每个长度为B的块用哈希函数计算出一个整数值h,将h为SHIFT表的索引值。

5、穷举P’中所有长度为B的块,对于每个块Bl,计算其相应的SHIFT表值。计算规则如下:找出Bl在P’的每个模式串中出现的最右位置,设这些位置中的最大值为j(以末尾位置为准),则SHIFT[h]=m-j。[注1]

6、其余所有不在P’中的块,SHIFT表值为m-B+1。[注2] [注3]


7、构建HASH表:设HASH[h]=p,p指向两个单独的表:PAT_POINT和PREFIX[注4]。有一个排序过的(根据模式串末B位的哈希值排序)指针链表PAT_POINT,存储着指向所有模式串的指针。p指向PAT_POINT中末B位哈希值为h的第一个节点。

8、构建PREFIX表:将每个模式串前B’位(B’的推荐值为2)的哈希值存入PREFIX表[注5],用于检查前缀是否匹配,可以进一步减少需要朴素匹配的模式串个数。

[注1] 等同于BM算法的“坏字符规则”

[注2] SHIFT表值为m-B+1的原因:这B个字符不出现在P’中,说明最多可能有(B-1)个字符出现在P’中,因此SHIFT表值为m-(B-1)=m-B+1。

[注3] 预处理的5、6步与原文表述的顺序不同,但效果是一样的。原文的做法是先将SHIFT表所有位置初始化为m-B+1,再根据本文的第5步更新SHIFT表值。参见原文第4页第1自然段。

[注4] 此处的表述是按照自己的理解总结得出的,可能不正确。原文第4~5页表述如下:“Let h be the hash value of the current suffix in the text and assume that SHIFT[h] = 0. The value of HASH[h] is a pointer p that points into two separate tables at the same time: We keep a list of pointers to the patterns, PAT_POINT, sorted by the hash values of the last B characters of each pattern. The pointer p points to the beginning of the list of patterns whose hash value is h. To find the end of this list, we keep incrementing this pointer until it is equal to the value in HASH[h+1] (because the whole list is sorted according to the hash values). So, for example, if SHIFT [h] 0, then HASH [h] = HASH [h+1] (because no pattern has a suffix that hash to h). In addition,
we keep a table called PREFIX, which will be described shortly.”

[注5] 预处理过程SHIFT、HASH和PREFIX表的内存位置关系图(根据个人对原文的理解画出,可能不正确):


SHIFT表的构造
不用等到实际考查text时再计算SHIFT,我们预处理各pat就可以把SHIFT表填上。对于每个pat,计算其每个长度为Bsubpat(aj-B+1…aj)的值,SHIFT[hashFun(subpat)]=min{m-B+1,m-j}
HASH表的构造
记现正扫描的text的末B位的哈希值为h。那么HASH[h]的值是pp指向PAT_POINT中哈希值为h的第一个结点处)。
HASH[]表大小同SHIFT,但相对就稀疏多了,人那儿存着所有可能的组合的SHIFT值。哎,牺牲空间换时间,时空一向两难全。
PREFIX表的构造
对每一个pat,要记录其首B’位字符的哈希值(PREFIX)。

复杂度OBN/M),BM含义同前,Ntext字符数。Patterns很短或很少的时候,Wu-Manber不是很牛叉。而成千上万的patterns一起匹配过去,Wu-Manber牛气冲天了。
posted @ 2016-03-16 21:13  StevenLuke  阅读(1548)  评论(0编辑  收藏  举报