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 %d ", ans1, ans2); 83 } 84 return 0; 85 }