KMP算法

KMP算法

kmp算法是一种改进的字符串匹配算法,由D.E.KnuthV.R.PrattJ.H.Morris同时发现,因此人们称它为克努特――莫里斯――普拉特操作(简称KMP算法)。KMP算法的关键是根据给定的模式串W1,m,定义一个next函数。next函数包含了模式串本身局部匹配的信息。

next数组的长度就是T串的长度,有如下定义:

j=0时,next[j]=-1

j>0时,next[j]=MAX{k|0<k<j,且‘T0...Tk-2=Tj-k...Tj-1}当此集合不为空;

其它情况,next[j]=0,其它情况

字符串和待匹配字符串都是从0开始计算的,和有的书上讲的从1开始是不同的。

朴素匹配算法:当比较几个(1---n)字符后,可能第一次比较就不相等,可能中间不相等,也可能最后一个不相等,但是都会退回到上次开始比较的后一个从新开始比较。

KMP算法:是不会退回比较的,一直向前。

代码如下:

#include <stdio.h>
void get_next(const char *T, int next[],int T_len)
{
int i = 0;
int j = -1;
next[0] = -1;
while(i<T_len - 1)
{
if(j == -1 || T[i] == T[j])
{
++i;
++j;
//  next[i] = j;  //没有改进的算法
if(T[i] != T[j])    //改进的算法
next[i] = j;
else
next[i] = next[j];
}
else
{
j = next[j];
}
}
}
int Index_KMP(const char *S, const char *T, int pos)
{
int next[255];
int i = pos;
int j = 0;
int T_length = 0;
while(T[T_length]!='\0')
{
T_length++;
}
get_next(T,next,T_length);
while(S[i]!='\0' && j!=T_length)
{
if(j == -1  || S[i] == T[j])
{
++i;
++j;
}
else
{
j = next[j];
}
}
if(j == T_length)
return i-T_length;
else
return -1;
}
int main()
{
char *S = "abcacaabaaaecdeaaaabacdeabcd";
char *T = "aaaa";
printf("%d\n",Index_KMP(S,T,0));
return 0;
}

改进的KMP算法,它是在计算出next值的同时,如果a位字符与它next值指向的b位字符相等,则该a位的nextval就指向b位的next_val值,如果不等,则该a位的nextval值就是它自己a位的next值。

你可能感兴趣的:(KMP)