KMP算法

KMP算法-简单匹配算法的改进

   KMP算法是D.E.Knuth、J.H.Morris和V.R.Pratt共同提出的,简称KMP算法。

           该算法较BF算法有较大改进,主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。

 在介绍KMP算法之前,首先介绍一个概念-真子串:、

          所谓真子串是指模式串t存在某个k(0<k<j),使得"t0t1…tk " = " tj-ktj-k+1…tj "成立。

         例如,t= "abab",

          即t0t1=t2t3

           也就是说, “ab”是真子串。

        真子串就是模式串中隐藏的信息,利用它来提高模式匹配的效率。

模式串t=“abcac”,用next数组存放这些“部分匹配”信息 。

 

j

0

1

2

3

4

t[j]

a

b

c

a

c

next[j]

-1

0

0

0

1

      归纳起来,定义next[j]函数如下:

                       max{k|0<k<j,且“t0t1…tk-1”=“tj-ktj-k+1…tj-1” }                                    

                                              当此集合非空时

                        -1                     当j=0时

                         0                    其他情况

t=“abab”对应的next数组如下:

j

0

1

2

3

t[j]

a

b

a

b

next[j]

-1

0

0

1

       设主串s的长度为n,子串t长度为m

        在KMP算法中求next数组的时间复杂度为O(m),在后面的匹配中因主串s的下标不减即不回溯,比较次数可记为n,所以KMP算法总的时间复杂度为O(n+m)

匹配示意图如下:

KMP算法的实现如下:

#include "sqstring.cpp"
void GetNext(SqString t,int next[])  /*由模式串t求出next值*/
{
	int j,k;
	j=0;k=-1;next[0]=-1;
	while (j<t.length-1) 
	{	
		if (k==-1 || t.data[j]==t.data[k]) 	/*k为-1或比较的字符相等时*/
		{	
			j++;k++;
			next[j]=k;
       	}
       	else  k=next[k];
	}
}
int KMPIndex(SqString s,SqString t)  /*KMP算法*/
{
	int next[MaxSize],i=0,j=0;
	GetNext(t,next);
	while (i<s.length && j<t.length) 
	{
		if (j==-1 || s.data[i]==t.data[j]) 
		{
			i++;j++;  			/*i,j各增1*/
		}
		else j=next[j]; 		/*i不变,j后退*/
    }
    if (j>=t.length)
		return(i-t.length);  		/*返回匹配模式串的首字符下标*/
    else  
		return(-1);        		/*返回不匹配标志*/
}
void main()
{
	SqString s,t;
	StrAssign(s,"ababcabcacbab");
	StrAssign(t,"abcac");
	printf("s:");DispStr(s);
	printf("t:");DispStr(t);
	printf("位置:%d\n",KMPIndex(s,t));
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值