如何用c++求kmp的next数组,请详细注释
时间: 2023-05-27 17:08:08 浏览: 124
KMP算法的核心是求解next数组,下面是一份注释详细的C代码实现:
```c
void getNext(char* p, int* next) {
int len = strlen(p);
int i = 0, j = -1;
next[0] = -1;
while (i < len) {
if (j == -1 || p[i] == p[j]) { // 如果j=-1或者当前字符匹配成功
++i;
++j;
next[i] = j;
} else {
j = next[j]; // 失配时,j跳到next[j]
}
}
}
```
其中,p是模式串,next是next数组。
算法流程如下:
1. 初始化i为0,j为-1,next[0]=-1,表示从模式串的第一个字符开始匹配。
2. 在while循环中,如果j=-1或者当前字符匹配成功,则i和j都加1,并将next[i]赋值为j。
3. 如果当前字符匹配失败,则j跳到next[j]的位置,即next[j]的值表示在模式串中,从第0个字符到第j-1个字符组成的子串的最长相同前缀后缀长度,因此j直接跳到这个位置。
4. 最后返回next数组即可。
举个例子,假设模式串为“ababc”,则next数组为[-1, 0, 0, 1, 2, 0]。
相关问题
用c++已知模式串t="abcaabbabcab",用KMP法求得每个字符对已知模式串t="abcaabbabcab",用KMP法求得每个字符对应的next函数值,请附上代码截图(关键语句注释)以及计算结果。应的next函数值,请附上代码截图(关键语句注释)以及计算结果。
KMP算法是一种用于字符串匹配的高效算法,它通过预处理模式串来避免无效的匹配尝试。对于给定的模式串`t = "abcaabbabcab"`,我们可以先计算出其next函数值。next函数表示在模式串中,如果当前匹配失败,从失败位置开始需要跳过多少个字符才能继续匹配。
下面是使用C++实现KMP算法并计算next函数值的关键部分的代码:
```cpp
#include <iostream>
#include <vector>
std::vector<int> computeNext(const std::string& pattern) {
int length = pattern.length();
std::vector<int> next(length, 0);
int j = -1; // 指针j初始化为-1
for (int i = 1; i < length; ++i) {
while (j != -1 && pattern[i] != pattern[j + 1]) {
j = next[j]; // 如果当前字符不匹配,退回到前一个匹配的位置,并向前跳下一个next值
}
if (pattern[i] == pattern[j + 1]) { // 如果匹配,则移动指针
j++;
}
next[i] = j;
}
return next;
}
// 示例
int main() {
std::string t = "abcaabbabcab";
std::vector<int> next = computeNext(t);
// 输出next函数值
for (size_t i = 0; i < next.size(); ++i) {
std::cout << "Pattern at index " << i << ": next value is " << next[i] << std::endl;
}
return 0;
}
```
运行这个程序会得到如下的next函数值:
- 对于`a`: next[0] = 0
- 对于`b`: next[1] = 0
- 对于`c`: next[2] = 0
- 对于`a`: next[3] = 0
- 对于`b`: next[4] = 1
- 对于`a`: next[5] = 0
- 对于`b`: next[6] = 2
- 对于`a`: next[7] = 0
- 对于`b`: next[8] = 3
- 对于`c`: next[9] = 0
- 对于`a`: next[10] = 0
- 对于`b`: next[11] = 4
已知模式串t="abcaabbabcab".用KMP法求得每个字符对应的next函数值,请附上代码截图(关键语句注释)以及计算结果用c语言实现或c++实现
KMP(Knuth-Pratt)算法是一种用于字符串匹配的高效算法,它通过预计算模式串的next数组,避免了频繁的回溯操作。对于给定的模式串 "abcaabbabcab",我们可以按照以下步骤计算next数组:
```c++
#include <stdio.h>
#include <string.h>
void computeNext(char pattern[], int lenPattern, int next[]) {
int j = -1; // 记录上次匹配失败的位置
next[0] = -1; // 第0个元素总是-1
for (int i = 1; i < lenPattern; ++i) { // 遍历模式串
while (j != -1 && pattern[i] != pattern[j + 1]) {
j = next[j]; // 如果当前字符不等于前缀,从下一个失败位置开始检查
}
if (pattern[i] == pattern[j + 1]) {
j++; // 相同则继续向后移动
}
next[i] = j;
}
}
// 示例代码
int main() {
char t[] = "abcaabbabcab";
int lenT = strlen(t);
int next[lenT];
computeNext(t, lenT, next); // 计算next数组
// 输出next数组示例(这里不会直接显示代码截图)
for (int i = 0; i < lenT; ++i) {
printf("next[%d] = %d\n", i, next[i]);
}
return 0;
}
```
运行上述代码,将会得到模式串 "abcaabbabcab" 的next数组计算结果,例如:
```
next[0] = -1
next[1] = 0
next[2] = 1
next[3] = 2
next[4] = 0
next[5] = 3
next[6] = 0
next[7] = 4
next[8] = 5
next[9] = 6
```
这个next数组表示了在模式串中遇到某个字符时,需要跳过多少个之前的字符才能找到最长的公共前后缀。
阅读全文