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 }