// 根据模式串构建 next 数组
void buildNext(const char *pattern, int *next) {
int i, j;
int m = (int)strlen(pattern);
next[0] = -1;
for (j = 1; j < m; j++) {
i = next[j - 1];
while (i >= 0 && (pattern[i + 1] != pattern[j])) {
i = next[i];
}
if (pattern[i + 1] == pattern[j]) {
next[j] = i + 1;
} else {
next[j] = -1;
}
}
}
// KMP算法
int KMP(char *text, char *pattern) {
// 1. 输入检查
if (text == NULL || pattern == NULL) {
return -1;
}
int N = (int)strlen(text);
int M = (int)strlen(pattern);
if (N == 0 || M == 0 || N < M) {
return -1;
}
// 2. 循环判断
int i = 0, j = 0;
int *next = (int *)malloc(sizeof(int) * M);
buildNext(pattern, next);
// 主串和模式串, 任意一个指针到达末尾的时候, 搜索结束
while (i < N && j < M) {
if (text[i] == pattern[j]) {
i++;
j++;
} else if (j > 0) {
// 1. i 不需要回溯
// 2. j 的值通过 next函数获取
j = next[j - 1] + 1;
} else {
// 如果 j == 0, 那么 i++ 移动到主串的下一个位置继续匹配
i++;
}
}
free(next);
return (j == M) ? (i - M) : -1;
}