WAYNETS.ORG

Game and Program

KMP算法

作者:

发表于

Context Polling System Post-Processing Renderer

KMP(Knuth-Morris-Pratt)算法是一种经典的字符串匹配算法,用于在一个主串中快速查找一个模式串(子串)是否出现过,并返回其位置。它的时间复杂度是 O(n + m),其中 n 是主串长度,mmm 是模式串长度。

KMP的核心思想

构建一个next 数组(前缀函数),当模式串的某个位置匹配失败时,我们可以利用已经匹配的信息,将模式串向右移动,不用重新从头比较。

如何构建next数组?

i012345
chababca
next001201
vector<int> buildNext(const string& pattern) 
{
    int m = pattern.size();
    vector<int> next(m, 0);
    int j = 0; // 前缀末尾指针

    for (int i = 1; i < m; i++) 
{
        while (j > 0 && pattern[i] != pattern[j])
            j = next[j - 1];
        if (pattern[i] == pattern[j])
            j++;
        next[i] = j;
    }
    return next;
}

int KMP(string text, string pattern) 
{
    int n = text.size(), m = pattern.size();
    vector<int> next(m);

    // 构建next数组
    for(int i = 1, j = 0; i < m; i++)
    {
        while(j > 0 && pattern[i] != pattern[j])
        {
            j = next[j - 1];
        }
        if(pattern[i] == pattern[j]) j++;
        next[i] = j;
    }

    // KMP匹配
    for(int i = 0, j = 0; i < n; i++)
    {
        while(j > 0 && text[i] != pattern[j])
        {
            j = next[j - 1];
        }
        if(text[i] == pattern[j]) j++;
        if(j == m) return i - j + 1;
    }
    
    return -1;
}

Leave a comment