KMP算法的思想都是一样的,看了很多讲解,基本上都只是在next数组的表示上是有区别的,我觉得一个很6的大神,讲的很好:
http://blog.csdn.net/v_JULY_v/article/details/6545192
这位大神的next【i】表示的是如果模板串p的第i位与母串s匹配失败,则从模板串的哪个位置开始进行下一次比较。
母串s和模板串p都是从0开始到len-1,next数组也是从0开始,next【0】=-1,next【1】=0。next【2】之后才根据情况求出来,具体看大神讲解
这里就把大神代码摘下来,写点注释,讲一下我的理解。
首先是next数组的初始化,这里大神做了优化,我只摘优化后的
//代码4-1
//修正后的求next数组各值的函数代码
void get_nextval(char const* ptrn, int plen, int* nextval)
{
int i = 0;
nextval[i] = -1;
int j = -1;
while( i < plen-1 ) //因为是先比价i<len再i+1,所以到len-1就可以
{
if( j == -1 || ptrn[i] == ptrn[j] )
{
++i;
++j;
if( ptrn[i] != ptrn[j] ) //++i,++j之后,再次判断ptrn[i]与ptrn[j]的关系
nextval[i] = j; //之前的错误解法就在于整个判断只有这一句。
else //如果相等那么p[i]不匹配p[j]一定也不匹配
nextval[i] = nextval[j];//那么就相当于找p[j]不匹配的话从哪个位置比
}
else //如果不相等就要再往前找相等的前后缀
j = nextval[j];
}
}
然后是KMP,这个比较好理解
//代码5-1
//int kmp_seach(char const*, int, char const*, int, int const*, int pos) KMP模式匹配函数
//输入:src, slen主串
//输入:patn, plen模式串
//输入:nextval KMP算法中的next函数值数组
int kmp_search(char const* src, int slen, char const* patn, int plen, int const* nextval, int pos)
{
int i = pos;
int j = 0;
while ( i < slen && j < plen )
{
if( j == -1 || src[i] == patn[j] )//从起点开始比了或者两个相等
{
++i;
++j;
}
else
{
j = nextval[j];
//当匹配失败的时候直接用p[j_next]与s[i]比较,
//下面阐述怎么求这个值,即匹配失效后下一次匹配的位置
}
}
if( j >= plen )
return i-plen;
else
return -1;
}
当然啦我只是谈了谈我的理解,可能有不妥,请见谅。