KMP算法——next数组
最近在学习数据结构,学到了KMP算法。起初只知道KMP算法的目的,就是让模式串向右滑动尽可能远的距离,也理解算法的目的。但是对其中next数组的含义和求解,还是不太清楚。经过一番思考,恍然大明白,在这里记录分享一下。
next数组的含义
首先贴一个我认为比较好理解的说明:如何更好的理解和掌握 KMP 算法
KMP算法的核心,是一个被称为部分匹配表(Partial Match Table)的数组。(引用自上述回答)
next数组是一个长度为n(模式串的长度)的数组。
next数组的下标:代表着模式串的子串的长度,子串长度肯定不能为0,所以next数组有意义的数值是从next[1]开始的,一直到n-1,也就是最大子串的长度。
next数组的元素:从上面的链接里的说明可以知道,next数组里记录的是子串信息,从长度为1的子串开始,到n-1子串结束,记录了它们前后缀最大公共子串的长度(这个子串是指前后缀的子串)。
结合上面所说的,我们计算出每个子串的前后缀最大公共子串长度后,放在从next[1]到next[n-1]的元素中,next[0]的位置放置-1。这样就是有些文章里面说的把最大公共子串长度“右移”一个位置的原因。
知道了next数组里面放的是什么就可以计算它了:
void get_next(string s, int next[]) {
size_t len = s.length();
// 模式串自匹配
int i = 0;
int j = -1;
next[0] = -1;
// 循环len - 1次,计算长度从1到len-1的子串信息
while (i < len - 1) {
// 用前缀匹配后缀,计算最多匹配的长度,就是当前子串长度下,公共子串的长度
if (j == -1 || s[i] == s[j]) {
++i;
++j;
next[i] = j;
}
// 不匹配的话,寻找当前长度为i的串的子串的最大公共长度
else
j = next[j];
}
}