KMP算法中next数组的构建

记得初学$kmp$的时候 老师让大家把它直接背下来

然而不理解的话 不仅调试起来比较慢 很多题目也难往$kmp$上想

-----------------------------------------------------------------------

设字符串为$s$ 长度为$len$ 起始位置为$1$ 

首先要明白的就是 next数组的意思 便是$s[$从 $1$ 到$ i]$的后缀与$s[$从 $1$到 $i -1]$的前缀的最长公共部分长度

$($假设为$k$,则$s[$从$ 1$ 到$ i]$与$s[$从$i  -  k$ 到 $i - 1]$匹配$)$

此处可参见NOI2014动物园的题目描述$($只用看题目描述里对$next$数组的解释便可 题目无需思考$)$

于是我们便可以开始构建$next$数组了

#include <bits/stdc++.h>
using namespace std;
const int N = 100;
char s[N];
int next[N];
int len;
int main()
{
    scanf("%s",s + 1);
    len = strlen(s + 1);
    next[1] = 0;
    int j = 0;
    for(int i = 2;i <= len; ++i)
    {
        while(j && s[i] != s[j + 1])j = next[j];
        //不断向前寻找 直到s[从1到i]的后缀与s[从1到j+1]匹配
        //之所以j=next[j]的原因是s[从1到j]的后缀与s[从1到next[j]]匹配
        //不同的只是s[j+1]与s[next[j]+1] 这一点也可以解释为何只需最后一位匹配
        if(s[i] == s[j + 1])
            next[i] = ++j;
        //若匹配成功 则最长公共部分长度为n+1
        else
            next[i] = 0;
        //否则 无公共部分
    }
    for(int i = 1;i <= len; ++i)
        printf("%d ", next[i]);
}

自认为字符串下标从$1$开始 比从$0$开始 使人更易理解$next$数组的含义$($然而大部分$kmp$模板中字符串下标都是从$0$开始的$)$

原文地址:https://www.cnblogs.com/sagitta/p/4625383.html