KMP算法——串的朴素模式匹配算法的优化、KMP算法的优化

什么是串的模式匹配

串的模式匹配:在主串中找到与模式串相同的字串,并返回其所在位置
例如:

主串:S='sdkjfklajsflkjlaskjf'
字串:'sdk'、'dkj'、'jfk'........
模式串:'as'、'flk'

朴素(简单)模式匹配算法

int Index(SString S,SString T){
	int k=1;//指向主串起始位置
	int i=1,j=1;//i指向主串起始位置,j指向模式串起始位置
	while(i<=S.length&&j<=T.length){
	if(S.ch[i]==T.ch[j]){
		++i;
		++j;
		}else{//如果S.ch[i]!=T.ch[j],k向后移动
		k++;
		i=k;//i指向下一个位置
		j=1;//j指向起始位置
		}
	}
	if(j>t.length)
		return k;
	else
		return 0;
}

性能分析

若模式串的长度为m,主串长度为n,
较好的情况:每个字串第一个字符就与模式串不匹配
匹配成功最好时间复杂度:O(m)
匹配失败时间复杂度:O(n-m+1)=O(n-m)约等于O(n)

最坏的情况:每个字串最后一个字符就与模式串不匹配,则直到匹配成功/失败最多需要(n-m+1)*m次比较
最坏时间复杂度为:O((n-m+1)*m)=O(nm)

朴素模式匹配算法的缺点:当某些子串与模式串能够部分匹配时,主串的扫描指针i经常回溯,导致时间开销增加。

KMP算法——串的朴素模式匹配算法的优化

由D.E.Knuth,J.H.Morris和V.R.Pratt提出,因此称为KMP算法。
设计思路:主串的指针不回溯,只有模式串的指针回溯。

/*KMP实现代码*/
Int Index_KMP(SString S,SString T,int next[]){//传入next数组
	int i=1,j=1;
	while(i<=S.length&&j<=T.length){
		if(j==0||S.ch[i]==T.ch[j]){
		++i;
		++j;//继续比较后继字符
		}
		else j=next[j];//模式串向后移动
	}
	if(i>T.length)
		return i-T.length;//匹配成功
	else
		return 0;
}

求next数组
串的前缀:包含第一个字符,且不包含最后一个字符的子串
串的后缀:包含最后一个字符,且不包含第一个字符的子串
当第j个字符匹配失败时,由前1~j-1个字符组成的串记为S,则:next[j]=S的最长相等前后缀长度+1(就是使S有最长前缀与最长的后缀相等,然后记下这个长度,并加1,就是next[j]的大小,即next[j]=最长重合的前后缀长度+1)
特别地,next[1]=0,(next[1]=0,next[2]=1)

/*求模式串T的next数组*/
void get_next(SString T,int next[]){
	int i=1,j=0;
	next[1]=0;
	while(i<T.length){
		if(j==0||T.ch[i]==T.ch[j]){
		++i;
		++j;
		next[i]=j;//next[j+1]=next[j]+1
		}
		else j=next[j];//否则让j=next[j]循环继续
	}
}

KMP算法性能分析
O(m)+O(n)=O(m+n)
O(m)是求next数组的时间复杂度
O(n)是KMP算法的时间复杂度

KMP算法优化——nextval数组

nextval数组就是对next数组的优化

/*nextval数组的求法*/
//先算出next数组,令nextval[1]=0
for(int j=2;j<T.length;j++){
	if(T.ch[next[j]]==T.ch[j])
		nextval[j]=nextval[next[j]];//从前往后找串中字符相等的字符,使后边数组元素等于前边的数组元素
	else
		nextval[j]=next[j];
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值