static INT MatchBytesKMP(IN const UCHAR* pText, IN INT iTextBytes, IN const UCHAR* pPattern, IN INT iPatternBytes, IN BOOL bCheckParameter = TRUE); // 内存字节匹配;KMP算法;
INT DiySystem::MatchBytesKMP(IN const UCHAR* pText, IN INT iTextBytes, IN const UCHAR* pPattern, IN INT iPatternBytes, IN BOOL bCheckParameter /*= TRUE*/) { //我只想说,真TM绕... //KMP算法:正向取匹配个数Match,如果==模式串长度则返回,否则后移(Match-对应匹配值),对应匹配值即匹配表[Match-1] // //模式串部分匹配值,也称共有元素最大长度、最大对称值... //比如 //"A"的前缀和后缀都为空集,共有元素的长度为0; //"AB"的前缀为[A],后缀为[B],共有元素的长度为0; //"ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0; //"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0; //"ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1; //"ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2; //"ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。 //Match[0] = 0 //Match[1] = 0 //Match[2] = 0 //Match[3] = 0 //Match[4] = 1 //Match[5] = 2 //Match[6] = 0 if (bCheckParameter) { if (!pText || iTextBytes <= 0 || !pPattern || iPatternBytes <= 0 || iPatternBytes > iTextBytes || IsBadReadPtr(pText, iTextBytes) || IsBadReadPtr(pPattern, iPatternBytes)) { return -1; } } //构建模式串匹配值表 vector<INT> vecPartMatch(iPatternBytes, 0); //首字符的最大对称值为0 for (INT i = 1, j = 0/*上一个位置的最大对称值*/; i < iPatternBytes; i++) { while (j > 0 && pPattern[i] != pPattern[j]) { j = vecPartMatch[j - 1]; //j将循环递减,注意vecPartMatch[j] < j总是成立 } if (pPattern[i] == pPattern[j]) { j++; //增加j的唯一方法 } vecPartMatch[i] = j; //获取最终值 } for (INT i = 0, iMatch = 0; i <= iTextBytes - iPatternBytes;) { iMatch = 0; //正向匹配数 for (INT j = 0; j < iPatternBytes; j++) { if (pPattern[j] != pText[i + j]) { break; } iMatch++; } if (iMatch == iPatternBytes) { return i; } else if (0 == iMatch) { i++; } else { i += (iMatch - vecPartMatch[iMatch - 1]); } } return -1; }