BNDM字符串匹配算法

horspool算法从右往左匹配,它跳转的时候只利用了一个字符的信息,这样使得跳转会比较短,速度比较慢。

BNDM算法是一种跳转时考虑子串的算法。具体实现的时候,为了提高速度,用了跟SHIFT AND一样的技巧。对于字符集里的每个字符,计算它在模式串的哪些位置出现,然后用一个整数表示这个集合。用一个整数D表示当前活跃的状态,第i位为1,表示在模式串i的位置有一个子串匹配到了,子串的具体长度取决于源串匹配的情况。如果D里第m位为1,这时候表示找到了模式串的一个前缀,如果这时候源串也匹配了m个字符,则表示找到了模式串,否则,只是一个子串,这时候要调整一个跳转的长度。跳转的长度为m-这个前缀的长度。每找到一个前缀都要更新一个跳转的距离,所以跳转的距离是越来越短。

 1 int BNDMMatch(byte* pSrc, int nSrcSize, byte* pSubSrc, int nSubSrcSize)
 2 {
 3     unsigned int skip[256] = {0}; 
 4     for(int i = 0; i < nSubSrcSize; i++)
 5     {
 6         skip[ pSubSrc[i] ] |= 1 << (nSubSrcSize - 1 - i);
 7     }
 8 
 9     int nPos = 0;
10     while(nPos <= nSrcSize - nSubSrcSize)
11     {
12         int j = nSubSrcSize -1;
13         int last = nSubSrcSize;
14         unsigned int D = -1;
15         while(D)
16         {
17             D &= skip[pSrc[nPos + j]];
18             if (D & (1<<(nSubSrcSize-1)))
19             {
20                 if (j > 0)
21                 {
22                     last = j;
23                 }
24                 else                    
25                 {
26                     return nPos;
27                 }
28             }
29             j--;
30             D <<= 1;
31         }
32         nPos += last;
33     }
34     return -1;
35 }

 

点赞