这里贴出相应代码,作为记录
#include <stdio.h>
#include <string.h>
// 字符串匹配
int BF(char* s, char* t, int n, int m);
int KMP(char* s, char* t, int n, int m);
void getNext(char* s, int* nxt, int n);
int main() {
char s[20], t[20];
int n, m;
scanf("%s", s);
scanf("%s", t);
scanf("%d%d", &n, &m);
// printf("%d", BF(s, t, n, m));
printf("%d", KMP(s, t, n, m));
}
void getNext(char* s, int* nxt, int n) {
int j = 0;
nxt[0] = 0;
for (int i = 1; i < n; i++) {
while (j > 0 && s[i] != s[j]) {
j = nxt[j - 1]; // 不相等时回溯
}
if (s[i] == s[j])
j++;
nxt[i] = j;
}
}
int KMP(char* s, char* t, int n, int m) {
if (m == 0) return 0;
int nxt[m];
getNext(t, nxt, m); // 得到 next 数组
int j = 0;
for (int i = 0; i < n; i++) {
while (j > 0 && s[i] != t[j]) {
j = nxt[j - 1];
}
if (s[i] == t[j]) j++;
if (j >= m ) {
return i - m + 1;
}
}
return -1;
}
int BF(char* s, char* t, int n, int m) {
int i = 0, j = 0;
while (i < n && j < m) {
if (s[i] == t[j]) {
i++;
j++;
}
else {
i = i - j + 1; // 回退
j = 0;
}
if (j >= m) return (i - m); // 得到 子串在 模式串的初始位置
}
return -1;
}