串的模式匹配是串处理系统中的最重要操作之一,普通匹配算法的时间复杂度为O(m*n)。然而,KMP算法的算法时间复杂度为O(m+n),其主要改进是:当出现比较不等时,不需回溯指针,而是利用已经得到的部分匹配的结果将模式向后滑动尽可能远的距离。
KMP算法的本质是基于有限自动机理论,它简化了有限自动机的构造,只考虑当前节点匹配是否成功,即两个分支的走向,成功则j++,失败则转到next[i] 的节点继续。
#include "stdafx.h"
#include <iostream.h>
#include<string>
int* get_nextval(const char *s, int &len)
{
len = strlen(s);
int *next = new int[len];
int i = 0, j = -1;
next[0] = -1;
while(i<len-1) {
if (j == -1 || s[i] == s[j]) {
++i;
++j;
if (s[i] != s[j]) {
next[i] = j;
} else {
next[i] = next[j];
}
} else {
j = next[j];
}
}
return next;
}
int KMP(const char *s, const char *t)
{
int slen,tlen;
int i = 0, j = 0;
int *next = get_nextval(t, tlen);
slen = strlen(s);
while(i<slen && j<tlen) {
if(j == -1 || s[i] == t[j]) {
++i;
++j;
} else {
j = next[j];
}
}
delete[] next;
if(j >= tlen)
return i - tlen;
return -1;
}
int main(int argc, char *argv[])
{
char s[128], t[128];
sprintf(s, "%s", "abdldoa;djfadjfopajdofa");
sprintf(t, "%s", "a;dj");
int pos1 = KMP(s,t);
int pos2 = strstr(s,t) - s;
cout<<"KMP:"<<pos1<<endl;
cout<<"strstr:"<<pos2<<endl;
return 0;
}