原创文章,转载请注明来源!
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int *PrefixFunc(char *query);
int KMP(char *test, char *query)
{
if (test == NULL || query == NULL){
return -1;
}
int tLen = strlen(test);
int qLen = strlen(query);
int *Prefix;
Prefix = PrefixFunc(query);
if (Prefix == NULL){
return -1;
}
int q = -1;
int i;
for ( i = 0; i < tLen; i++){
while (q > -1 && query[q + 1] != test[i]){
q = Prefix[q];
}
if (query[q + 1] == test[i]){
q += 1;
}
if (q == qLen - 1){
cout<<"match in position"<<" "<<i - qLen + 1<<" "<<endl;
q = Prefix[q];
}
}
delete[] Prefix;
return 0;
}
int *PrefixFunc(char *query)
{
if (query == NULL){
return NULL;
}
int len = strlen(query);
int *Pre = new int[len];
if (Pre == NULL){
return NULL;
}
Pre[0] = -1;
int k = -1;
int q;
for(q = 1; q < len; q++){
while (k > -1 && query[k + 1] != query[q]){
k = Pre[k];
}
if (query[k + 1] == query[q]){
k = k + 1;
}
Pre[q] = k;
}
return Pre;
}
int main()
{
char *test = "bacbababaabcbab";
char *query = "abc";
KMP(test, query);
system("pause");
}
先贴上代码
要注意的是,由于算法导论中的伪代码数组都是从1开始的,而c语言中数组是从1开始的,所以说前缀函数Prefix中的-1代表不存在能转换的前缀,而算法导论中用0来表示