3.31数据结构之串的字串定位(KMP算法,模式匹配)

1.模式匹配

模式匹配也被成为暴力匹配,算法的思路在于,从第一个元素开始进行对比当出现不相等的情况,则从第二个元素开始进行对比,以此类推,直到全部匹配完为止。

因为该算法中,主串会需要进行回溯,当元素数量相当多的时候效率是非常低的。我们通过运算时间复杂度也可以看出来。

 代码实现(使用C语言,该串运用顺序存储结构)

int StrIndex(SeqString *S1,SeqString *S2,int pos){
	int i=pos,j=0;
	while(j<S2->len&&i<S1->len){
		if(S2->ch[j]==S1->ch[i]){
			i++;
			j++;
		}
		else{
			j=0;
			i=i-j+1;//下一次位置 
		}
	}
	if(j==StrLen(S2)){
		return i-StrLen(S2);
	}else{
		return -1;
	}
} 

2.KMP算法

模式匹配,我们可以知道,当从主串的第一个元素开始匹配出现不匹配情况的时候,要从第二个元素开始向后匹配。

如果我们可以直接找到和前面匹配过相同的元素的位置再向后进行匹配,那主串就不用进行回溯,时间复杂度就可以变为O(m)了。

接下来画个图来描述一下这种思想:

 KMP算法是一种改进的模式匹配算法,是由DEKnuth、JHMorris和VRPratt同时发现的,因此成为克努特——莫里斯——普拉特操作(简称KMP算法)

那么如何知道需要向后移动多少个位置?——>next数组

理想状态:

next数组用于匹配

 因此对于S1=“abaabcacd”对应的next数组为:next [  ] = {0,1,1,2,2,3,1,2,1}

"abaabcacd"

"abc" (c!=a,向后移动1个位置)

"  abc"(a!=b,向后移动1个位置)

"   abc"(b!=a,向后移动2个位置)

"      abc"(匹配成功)

也就是每次向后移动,都是子串的第next[j]个元素开始进行比较,因为前面的相等无需比较

代码实现:(运用C语言顺序串)

(注意:因为c语言的下标从0开始和上面举的例子有一点差异)

typedef struct{
	char ch[MAXSIZE];
	int len;
}SeqString;

//KMP算法
int next[100];

void GetNext(SeqString *t,int *next){
	int i=0,j=-1;
	next[0]=-1;
	while(i<t->len){
		if(j==-1||t->ch[i]==t->ch[j]){
			++i;
			++j;
			next[i]=j;
		}else{
			j=next[j];
		}
	}
}

//t为s的子串,求t在s中的位置索引 
int Index(SeqString *s,SeqString *t){
	int i=0,j=0;
	while(i<s->len&&j<t->len){
		if(j==-1||(s->ch[i]==t->ch[j])){
			i++;j++;
		}else{
			j=next[j];//t向右移 
		}
		if(j==t->len)
			return i-t->len;
		else 
			return -1;
	}
} 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值