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;
}
运行结果如下图: