kmp算法尽管只有几句代码,但是非常难理解,昨天跟代码走了好几遍,才渐渐晓得主要思想:
首先分析模式字符串,针对所有的前缀字符串(和全串)获取其所有前缀与后缀字符串的最大公共长度;
然后逐字符比较,遇到不匹配的只是移动模式字符串的指针(或者int型的索引,指示当前待比较的字符),而主串只是一直往后走,以下是demo:
1 #include <iostream> 2 3 using namespace std; 4 5 int force_search(char * s, int sl, char * p, int pl) 6 { 7 int i(0); 8 while ( i + pl <= sl) 9 { 10 int j(i), k(0); 11 while (k < pl) 12 if (s[j] == p[k]) 13 (j ++, k ++); 14 else 15 break; 16 if (k == pl) 17 return i; 18 ++ i; 19 } 20 return -1; 21 } 22 23 void print_int_arrays(int * arrays, int al) 24 { 25 for (int i(0); i < al; ++ i) 26 cout << arrays[i] << " "; 27 cout << endl; 28 } 29 30 void print_char_arrays(char * arrays, int cl) 31 { 32 for (int i(0); i < cl; ++ i) 33 cout << arrays[i] << " "; 34 cout << endl; 35 } 36 37 void get_nexts(char * p, int pl, int * nexts) 38 { 39 int j(0), k(-1); 40 nexts[0] = -1; 41 while (j < pl) 42 if (p[j] == p[k] || k == -1) 43 nexts[++ j] = ++ k; 44 else 45 k = nexts[k]; 46 } 47 48 int kmp_search(char * s, int sl, char * p, int pl) 49 { 50 int * nexts = new int[pl + 1]; 51 get_nexts(p, pl, nexts); 52 53 int i(0), j(0); 54 int indexbegin(0); 55 while (j < pl && i < sl) 56 if (s[i] == p[j]) 57 (++ i, ++ j); 58 else 59 { 60 indexbegin = i - nexts[j]; 61 0 == j ? ++ i :j = nexts[j]; 62 } 63 delete[] nexts; 64 return j == pl ? indexbegin : -1; 65 } 66 67 68 int main() 69 { 70 char * mstr = "aaabacaabacaabacabaabb"; 71 char * pstr = "abacab"; 72 73 for (int i = 0; i < 18; ++ i) 74 { 75 pstr = mstr + i; 76 cout << "========================" << endl; 77 cout 78 << force_search(mstr, strlen(mstr), pstr, strlen(pstr)) 79 << endl; 80 cout 81 << kmp_search(mstr, strlen(mstr), pstr, strlen(pstr)) 82 << endl; 83 } 84 85 return 0; 86 }
时间: 2024-12-11 18:57:56