Wu-Manber字符串多模式匹配
首先介绍预处理过程:
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表的内存位置关系图(根据个人对原文的理解画出,可能不正确):