static INT MatchBytesBM(IN const UCHAR* pText, IN INT iTextBytes, IN const UCHAR* pPattern, IN INT iPatternBytes, IN BOOL bCheckParameter = TRUE); // 内存字节匹配;Boyer-Moore算法;
INT DiySystem::MatchBytesBM(IN const UCHAR* pText, IN INT iTextBytes, IN const UCHAR* pPattern, IN INT iPatternBytes, IN BOOL bCheckParameter /*= TRUE*/) { // Boyer-Moore // BM算法是目前被认为最高效的字符串搜索算法,比KMP算法快3-5倍。 // // 从右往左进行比较匹配。 // 假设文本串pText长度N,模式串pPattern长度M // 好后缀规则和坏后缀规则:后移步长j += max(好后缀后移步长,坏后缀后移步长) //--> //HERE IS A SIMPLE EXAMPLE //EXAMPLE //坏后缀S(PText中),在文本串下标6,在模式串正本-1,坏后缀后移步长6-(-1)=7 //无好后缀 //--> //HERE IS A SIMPLE EXAMPLE // EXAMPLE //坏后缀P(PText中),在文本串下标6,在模式串正本4,坏后缀后移步长6-4=2 //无好后缀 //--> //HERE IS A SIMPLE EXAMPLE // EXAMPLE //坏后缀I(PText中),在文本串下标2,在模式串正本-1,坏后缀后移步长2-(-1)=3 //好后缀MPLE(PText中), //M在文本串下标6,在模式串正本0,后移步长6-0=6 //P在文本串下标5,在模式串正本5,后移步长5-5=0 //L在文本串下标4,在模式串正本4,后移步长4-4=0 //E在文本串下标3,在模式串正本3,后移步长3-3=0 //好后缀后移步长=max(6,0,0,0) //后移步长 = max(6,3) //--> //HERE IS A SIMPLE EXAMPLE // EXAMPLE //坏后缀P(PText中),在文本串下标6,在模式串正本4,坏后缀后移步长6-4=2 //无好后缀 //--> //HERE IS A SIMPLE EXAMPLE // EXAMPLE if (bCheckParameter) { if (!pText || iTextBytes <= 0 || !pPattern || iPatternBytes <= 0 || iPatternBytes > iTextBytes || IsBadReadPtr(pText, iTextBytes) || IsBadReadPtr(pPattern, iPatternBytes)) { return -1; } } //模式串字节首次出现下标表,[字节值]=下标,-1未出现该字符 vector<INT> vecPatternIndex(BYTE_MAX + 1, -1); for (INT i = 0; i < iPatternBytes; i++) { if (-1 == vecPatternIndex[pPattern[i]]) // 存储首次出现下标 { vecPatternIndex[pPattern[i]] = i; } } for (INT i = 0, iBad = 0, iGood = 0, iSkip = 0; i <= iTextBytes - iPatternBytes;) { iBad = 0; iGood = 0; for (INT j = iPatternBytes - 1; j >= 0; j--) { if (pPattern[j] != pText[i + j]) { break; } iGood++; // 好字符个数 } if (iGood == iPatternBytes) { return i; } else { iBad = iPatternBytes - iGood - 1; // 坏字符在文本串下标 if (iPatternBytes - 1 == iBad) //无好后缀 { i += (iBad - vecPatternIndex[pText[i + iBad]]); // vecPatternIndex[pText[i + iBad]] 坏字符在模式串首出现下标 } else { iSkip = 0; for (INT j = iPatternBytes - 1, k = 0; k < iGood; j--, k++) { // 右向左遍历所有好字符,max(好字符在文本串下标-好字符在模式串首出现下标,...) if (iSkip < j - vecPatternIndex[pText[i + j]]) // j 好字符在文本串下标 { iSkip = j - vecPatternIndex[pText[i + j]]; // vecPatternIndex[pText[i + j]] 好字符在模式串首出现下标 } } if (iSkip < iBad - vecPatternIndex[pText[i + iBad]]) // max(好字符步长,坏字符步长 ) { iSkip = iBad - vecPatternIndex[pText[i + iBad]]; } i += iSkip; } } } return -1; }