手算KMP算法nextval数组

上一篇文章介绍了手算KMP算法nextl数组
接下来就来介绍如何通过next数组求得nextval数组。
通过上篇得到的next数组进行讲解.

第一步:nextval数组的第一位必定为0;第二位模式串中元素的值如果与第一位相同则为0,不同为1。

下标 1 2 3 4 5 6 7 8 9
模式串 a b a a b c a b a
next 0 1 1 2 2 3 1 2 3
nextval 0 1

第二步:第 3 个元素的next值为 1 ,于是将其与下标为 1 的元素的值进行比较;通过比较,第 3 个元素和第 1 个元素的值都为 a ,因此第 3 个元素的nextval为 0

### KMP算法中的nextval数组动计方法 #### nextval数组的概念 `nextval`数组是对`next`数组的一种优化形式,目的是减少不必要的回溯操作。通过对比模式串的当前字符与其对应的前缀字符来决定是否可以直接跳过某些匹配位置。 --- #### 动计nextval数组的具体步骤 以下是基于引用内容总结的动计`nextval`数组的方法: 1. **初始化** 定义`nextval[1] = 0`(假设模式串下标从1开始)。如果模式串下标从0开始,则定义`nextval[0] = -1`[^5]。 2. **求解`next`数组** 首先按照标准方式动计出`next`数组的值。这是后续计`nextval`的基础[^3]。 3. **逐位填充`nextval`数组** 对于每一个位置`j`(`j > 1`),判断模式串的第`j`个字符与第`next[j]`个字符的关系: - 如果`T[j] == T[next[j]]`,则令`nextval[j] = nextval[next[j]]`。 - 否则,令`nextval[j] = next[j]`。 4. **特殊情况处理** 当`next[j] == 0`时,直接设置`nextval[j] = 0`,因为此时不存在更短的有效前缀后缀匹配。 --- #### 示例说明 假设有模式串 `ABABCABAA`,我们逐步演示如何动计`nextval`数组。 ##### 步骤1:计`next`数组 | 模式串 | A | B | A | B | C | A | B | A | A | |--------|---|---|---|---|---|---|---|---|---| | 下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | | next[] | 0 | 0 | 1 | 2 | 0 | 1 | 2 | 3 | 1 | ##### 步骤2:计`nextval`数组 根据上述规则逐一计每个位置的`nextval`值: - 初始条件:`nextval[0] = -1` 或者 `nextval[1] = 0`(取决于下标起始)。 - 对于`j=2`到`j=8`的位置依次计: - `j=2`: `T[2] != T[next[2]]=T[1]`,所以`nextval[2] = next[2] = 1`。 - `j=3`: `T[3] != T[next[3]]=T[2]`,所以`nextval[3] = next[3] = 2`。 - `j=4`: `T[4] != T[next[4]]=T[0]`,所以`nextval[4] = next[4] = 0`。 - `j=5`: `T[5] != T[next[5]]=T[1]`,所以`nextval[5] = next[5] = 1`。 - `j=6`: `T[6] != T[next[6]]=T[2]`,所以`nextval[6] = next[6] = 2`。 - `j=7`: `T[7] == T[next[7]]=T[3]`,所以`nextval[7] = nextval[next[7]] = nextval[2] = 1`。 - `j=8`: `T[8] != T[next[8]]=T[1]`,所以`nextval[8] = next[8] = 1`。 最终得到的结果如下表所示: | 模式串 | A | B | A | B | C | A | B | A | A | |-----------|----|----|----|----|----|----|----|----|----| | 下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | | next[] | 0 | 0 | 1 | 2 | 0 | 1 | 2 | 3 | 1 | | nextval[] | -1 | 0 | 1 | 2 | 0 | 1 | 2 | 1 | 1 | --- #### 实现代码示例 以下是一个简单的C++代码用于自动计`nextval`数组: ```cpp void getNextVal(const string& pattern, vector<int>& nextval) { int n = pattern.size(); nextval.resize(n); nextval[0] = -1; int i = 0, j = -1; while (i < n - 1) { if (j == -1 || pattern[i] == pattern[j]) { ++i; ++j; if (pattern[i] != pattern[j]) nextval[i] = j; else nextval[i] = nextval[j]; } else { j = nextval[j]; } } } ``` --- #### 总结 通过以上分析可以看出,`nextval`数组的核心思想是在`next`数组的基础上进一步优化,减少了重复比较的可能性。这种优化对于提高KMP算法的实际效率具有重要意义。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值