Algorithm_字节匹配_003_KMP


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;
}

猜你喜欢

转载自www.cnblogs.com/dailycode/p/9644403.html