KMP

KMP O(n)

ZERO版

next[i]:在i之前的子串和从0开始的最大相等子串长度-1

ne[i]=ji的位置失配该回退的位置j

// 下标从0开始
// s是长文本, t是模式串

// 求模式串的next数组:
int ne[t.size()];
ne[0] = -1;
for (int i = 1, j = -1; i < t.size(); i ++ )
{
    while (j >= 0 && t[i] != t[j + 1]) j = ne[j];
    if (t[i] == t[j + 1]) j ++ ;
    ne[i] = j;
}
// 匹配
for (int i = 0, j = -1; i < s.size(); i ++ )
{
    while (j >= 0 && s[i] != t[j + 1]) j = ne[j];
    if (s[i] == t[j + 1]) j ++ ;
    if (j == t.size() - 1)
    {
        int pos = i - j;
        /* ...匹配成功后的逻辑... */
        j = ne[j]; // 继续回溯查找
    }
}

ONE版

next[i]:表示以i为终点的后缀和从1开始的前缀相等,而且前后缀的长度最长

next[i]=j:表示在i的位置上, p[1~j] == p[i-j+1,i] 这两段子串相等

// 下标从1开始
// s[]是长文本, p[]是模式串, n是s的长度, m是p的长度

// 求模式串的next数组:
for (int i = 2, j = 0; i <= m; i ++ )
{
    while (j && p[i] != p[j + 1]) j = ne[j];
    if (p[i] == p[j + 1]) j ++ ;
    ne[i] = j;
}

// 匹配
for (int i = 1, j = 0; i <= n; i ++ )
{
    while (j && s[i] != p[j + 1]) j = ne[j];
    if (s[i] == p[j + 1]) j ++ ;
    if (j == m)
    {
        int pos = i - j;
        /* ...匹配成功后的逻辑... */
        j = ne[j];
    }
}
posted @ 2022-05-04 07:12  feiyucoder  阅读(37)  评论(0)    收藏  举报