KMP算法真的是“大牛”算法,我想了好几天才把它真正弄懂实现出来,真真不容易!啥都不说了,代码说明一切。
#include<iostream> using namespace std; #include<string> int Brute_Force(string S, string T) { unsigned int i = 0; unsigned int j = 0; int pos = -1; while (i < S.length()&&j < T.length()) { // 循环比较的条件 if (S[i] == T[j]) {// 如果相等 则继续比较 i++; j++; } else { // 不相等则让指向主串的“移动指针”i回溯,让指向模式串的“移动指针”j指向初始位置0 i = i - (j - 1); // 主串的“移动指针”i应该回溯(i-1)个单位 j = 0; } } // 如果j>=T.length() 则说明匹配成功 那么修改pos if (j >= T.length()) { pos = i - T.length(); return pos; } else {// 否则直接-1 return -1; } } // 获得next[]数组 void GetNext(string T, int next[]) { int j = 0; int k = -1; next[0] = -1; while (j < T.length()-1) { if (k == -1 || T[j] == T[k]) next[++j] = ++k; // 这里容易出错 else k = next[k]; } } // 获得nextVal数组 void GetNextVal(string T, int nextval[]) { int j = 0; int k = -1; nextval[0] = -1; while (j < T.length()-1 ) { if (k == -1 || T[j] == T[k]) { if (T[++j] == T[++k]) // 这句容易出错 nextval[j] = nextval[k]; else nextval[j] = k; } else k = nextval[k]; } } int KMP(string S, string T,int next[]) { int i = 0; // 主串的位置 int j = 0; // 模式串的位置 while (i < S.length() && j < T.length()) { if (S[i] == T[j]) { i++; j++; } else if (j == 0) i++; // 这句值钱 else j = j - (j - next[j]); //模式串指针回溯(j-next[j]) } if (j == T.length()) return i - j; else return -1; } int main() { string a = "aabdbababbbssdabacababcc"; string b = "abacababcc"; cout << Brute_Force(a, b) << endl; int* pnext = new int[b.length()]; int* pnextVal = new int[b.length()]; GetNext(b, pnext); for (int i = 0; i < b.length(); i++) { cout << pnext[i] << " "; } cout << endl; GetNextVal(b, pnextVal); for (int i = 0; i < b.length(); i++) { cout << pnextVal[i] << " "; } cout << endl; cout << KMP(a, b, pnext) << endl; delete[] pnext; delete[]pnextVal; return 0; }
运行结果如下图: