数据结构与算法 - 串
KMP字符串匹配算法
next数组的计算方法:
看该字符前的字符串的前缀和后缀有多少相同(可以交叉重叠),就让相同的数量值加一即为当前next值。
也可以这样计算:看前一个字符的next值处是否与前一个字符相同,若相同,则当前next值为上一next值加一;若不相同,则查看上一next值处的字符的next处于当前的字符是否相同,直到相同之后,让相同的值加一(如果到达最开头都不相同,则直接设置为1,总之就是到相同的位置的next值加一)。
下面是一个例子:
A | B | C | A | B | C | D |
---|---|---|---|---|---|---|
0 | 1 | 1 | 1 | 2 | 3 | 4 |
因此,在第一次失配时,如上图红框区域,j
指针直接回到了next[j]
的位置,当j
位于第一个时(即第一个就失配),i++并且j不变,以此类推
nextval数组的计算方法
规则:
对比当前next值处的字符是否与当前字符相同,若相同,则nextval也与那字符的nextval相同;若不同,则nextval与其next值相同;
例子:
索引 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
字符串 | a | b | a | b | a | a | a | b | a | b | a | a |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 | 2 | 2 | 3 | 4 | 5 | 6 |
nextval数组 | 0 | 1 | 0 | 1 | 0 | 4 | 2 | 1 | 0 | 1 | 0 | 4 |
解释: | 前一个是b,b和a不相同,到第一个,设置为1 | 前一个是a,与b不一样,和b还是不一样,和a一样,1+1=2 |
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
using namespace std;
#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN + 1];
void strLength(SString S) {
int m;
for (m = 1; S[m] != '\0'; m++);
S[0] = m - 1;
}
void get_next(SString T, int* next) {
int j = 1, k = 0;
next[1] = 0; // 初始化 next[1] 为 0
while (j < T[0]) { // T[0] 是串 T 的长度
if (k == 0 || T[j] == T[k]) {
j++;
k++;
next[j] = k;
}
else {
k = next[k];
}
}
}
int Index_KMP(SString S, SString T, int pos, int* next) {
int i = pos, j = 1; // i 指向主串 S 的当前字符,j 指向模式串 T 的当前字符
get_next(T, next); // 计算模式串 T 的 next 数组
while (i <= S[0] && j <= T[0]) {
if (j == 0 || S[i] == T[j]) { // 如果匹配,或 j = 0(即从头匹配)
i++;
j++;
}
else {
j = next[j]; // 如果失配,j 跳转到 next[j]
}
}
if (j > T[0]) return i - T[0]; // 匹配成功
else return 0; // 匹配不成功
}
int main() {
SString S, T;
int pos;
int next[MAXSTRLEN];
int r;
printf("输入主串 S: ");
scanf("%s", S + 1); // 跳过下标为 0 的元素
printf("输入模式串 T: ");
scanf("%s", T + 1); // 跳过下标为 0 的元素
printf("输入起始位置 pos: ");
scanf("%d", &pos);
strLength(S); // 求主串 S 的长度
strLength(T); // 求模式 T 的长度
if (r = Index_KMP(S, T, pos, next))
printf("模式串在主串中的位置为: %d \n", r);
else printf("匹配失败!");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律