1 #include <stdio.h>
2 #include <string.h>
3
4 void computeLPSArray(char* pattern, int* lps) {
5 int len = 0; // 最长前缀后缀匹配长度
6 int i = 1;
7
8 lps[0] = 0;
9
10 while (pattern[i] != '\0') {
11 if (pattern[i] == pattern[len]) {
12 len++;
13 lps[i] = len;
14 i++;
15 } else {
16 if (len != 0) {
17 len = lps[len - 1];
18 } else {
19 lps[i] = 0;
20 i++;
21 }
22 }
23 }
24 }
25
26 void kmpSearch(char* text, char* pattern) {
27 int m = strlen(pattern);
28 int n = strlen(text);
29 int lps[m]; // 存储最长前缀后缀匹配长度
30
31 computeLPSArray(pattern, lps);
32
33 int i = 0; // text 的指针
34 int j = 0; // pattern 的指针
35
36 while (i < n) {
37 if (pattern[j] == text[i]) {
38 j++;
39 i++;
40 }
41
42 if (j == m) {
43 printf("在索引 %d 处找到匹配\n", i - j);
44 j = lps[j - 1];
45 } else if (i < n && pattern[j] != text[i]) {
46 if (j != 0) {
47 j = lps[j - 1];
48 } else {
49 i++;
50 }
51 }
52 }
53 }
54
55 int main() {
56 char text[100];
57 char pattern[100];
58
59 printf("请输入文本:");
60 fgets(text, sizeof(text), stdin);
61
62 printf("请输入要搜索的模式:");
63 fgets(pattern, sizeof(pattern), stdin);
64
65 // fgets 会将换行符也读入,所以需要手动将其替换为字符串结束符 '\0'
66 text[strcspn(text, "\n")] = '\0';
67 pattern[strcspn(pattern, "\n")] = '\0';
68
69 kmpSearch(text, pattern);
70
71 return 0;
72 }