1 //串的模式匹配算法
2 //KMP算法,时间复杂度为O(n+m)
3 #include <iostream>
4 #include <string>
5 #include <cstring>
6 using namespace std;
7
8 //-----串的定长顺序存储结构-----
9 #define MAXLEN 255 //串的最大长度
10 typedef struct {
11 char ch[MAXLEN + 1]; //存储串的一维数组
12 int length; //串的当前长度
13 }SString;
14
15 int Next[MAXLEN + 1];
16 int nextval[MAXLEN + 1];
17
18 int Index_KMP1(SString S, SString T, int pos)
19 {//利用模式串T的Next函数求T在主串S中的第pos个字符之后的位置
20 //其中,T非空,1<=pos<=S.length
21 int i = pos, j = 1;
22 while (i <= S.length && j <= T.length) //两个串均未比较到串尾
23 {
24 if (j == 0 || S.ch[i] == T.ch[j]) { ++i; ++j; } //继续比较后继字符
25 else j = Next[j]; //模式串向右移动
26 }
27 if (j > T.length) return i - T.length; //匹配成功
28 else return 0; //匹配失败
29 }
30
31 int Index_KMP2(SString S, SString T, int pos)
32 {
33 int i = pos, j = 1;
34 while (i <= S.length && j <= T.length)
35 {
36 if (j == 0 || S.ch[i] == T.ch[j]) { ++i; ++j; }
37 else j = nextval[j];
38 }
39 if (j > T.length) return i - T.length;
40 else return 0;
41 }
42
43 void get_next(SString T, int Next[])
44 {//求模式串T的Next函数值并存入数组Next
45 int i = 1, j = 0;
46 Next[1] = 0;
47 while (i < T.length)
48 {
49 if (j == 0 || T.ch[i] == T.ch[j]) { ++i; ++j; Next[i] = j; }
50 else j = Next[j];
51 }
52 }
53
54 void get_nextval(SString T, int nextval[])
55 {//求模式串T的Next函数修正值并存入数组nextval
56 int i = 1, j = 0;
57 nextval[1] = 0;
58 while (i < T.length)
59 {
60 if (j == 0 || T.ch[i] == T.ch[j])
61 {
62 ++i; ++j;
63 if (T.ch[i] != T.ch[j]) nextval[i] = j;
64 else nextval[i] = nextval[j];
65 }
66 else j = nextval[j];
67 }
68 }
69
70 int main()
71 {
72 SString A, B;
73 A.ch[0] = B.ch[0] = ' ';
74 while (scanf("%s%s", A.ch + 1, B.ch + 1) == 2)
75 {
76 A.length = strlen(A.ch + 1);
77 B.length = strlen(B.ch + 1);
78 get_next(B, Next);
79 get_nextval(B, nextval);
80 //修正之后匹配更快,结果相同
81 int ans1 = Index_KMP1(A, B, 1), ans2 = Index_KMP2(A, B, 1);
82 printf("%d\t%d\n", ans1, ans2);
83 }
84 return 0;
85 }