数据结构2.2串的模式匹配

本文介绍了串的模式匹配问题,包括Brute-Force算法的基本思想,即从目标串的指定位置开始逐字符比较,以及KMP算法,通过next[j]数组优化匹配过程,避免无效回溯,提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模式匹配

子串在主串中的定位操作称为串的模式匹配,记为index(s,t,pos),即在主串s中,从第pos个字符开始查找与子串t第一次相等的位置。若查找成功,则返回子串t的第一个字符在主串中的位序,否则返回0。其中主串称为目标串,子串称为模式串

Brute-Force算法

基本思想

从目标串的第pos个字符开始与模式串的第一个字符比较,若相等则继续逐个比较后续字符,否则从主串的第pos+1个字符重新和模式串进行比较。以此类推,若存在和模式串相等的子串,则匹配成功返回模式串t的第一个字符在目标串s中的位置;否则,匹配失败返回0。
Brute-Force算法如下

int index(string *s,string *t,int pos){
int i,j;
if(pos < 1 || pos > s->length || pos > s->length - t->length + 1){
return 0;
}//参数非法
i = pos - 1;
i = 0;
while(i < s->length && j < t->length){
	if(s->ch[i] == t->ch[j]){
		i++;
		j++;//继续匹配下一个字符
	}else{
		i = i - j + 1;
		j = 0;//主串、子串指针回溯,重新开始下一次匹配
}
}
if(j >= t->length){
	return i - t->length + 1;//返回主串中已匹配子串的第i个字符的位序
}else{
	return 0;//匹配不成功
}
}

该算法较简单且易于理解,但效率不高,因为目标串指针(i)的回溯消耗了大量时间。

KMP算法

讨论一般情况,设目标串s=“s0 s1 … sn-1”,模式串"t0 t1 … tm-1",当si != tj 时存在
"t0 t1 … tk-1" = “tj-k tj-k+1 … tj-1”(0<k<j)
则下一次比较可以直接从tk与si开始继续下一趟的匹配。若模式串中不存在子串
"t0 t1 … tk-1" = “tj-k tj-k+1 … tj-1”(0<k<j),则下一次比较从t0开始与si继续下一趟匹配。由此可见,k的取值可以由模式串的构成直接得出,与目标串s没有关系。
此时令next[j]=k,则next[j]表明当模式串中第j个字符与目标串中si“失配”时,在模式串中需重新和目标串字符si进行比较的字符位置。

next[j]的实现(修正后)
void getnext(string *t,int next[]){//由模式串t求出next值
int j,k;
j = 0;
k = -1;
next[0] = -1;
while(j < t->length){
	if(k == -1 || t->ch[j] == t->ch[k]){
		if(t->ch[j] != t->ch[k){
			next[j] = k;
		}else{
			next[j] = next[k];
	}else{
k = next[k];
}
}
KMP算法实现
int KMPindex(string *s,string *t,int pos){
int next[INIZSIZE],i,j;
getnext(t,next);
i = pos - 1;
j = 0;
while(i < s->length && j < t->length){
	if(j == -1 || s->ch[i] == t->ch[j]){
	i++;
	j++;
	}else{
	j = next[j];
	}
}
if(j >= t->length){
	return i - t->length + 1;
}else{
return 0;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值