4.2串的模式匹配概念

4.2串的模式匹配概念

BF暴力算法

//BF 暴力枚举
int index(SqString S, SqString P, int pos)
{
	int i = pos - 1, j = 0;
	while (i < S.length && j < P.length) {
		if (S.SString[i] == P.SString[j]) {
			i++; j++;//主串和子串依次匹配下一个字符
		}
		else {//主串、子串指针回溯重新开始下一次匹配
			i = i - j + 1;//主串从下一个位置开始匹配
			j = 0;//子串从头开始匹配
		}
	}
	if (j >= P.length)
		return (i - P.length);//返回匹配的第一个字符的下标
	else
		return -1;//模式匹配不成功
}

BF算法分析:
若设n为目标S的长度,m为模式P的长度,匹配算法最多比较n - m + 1趟。若每趟比较都比较到模式P尾部才出现不等,要做m次比较,则在最坏的情况下,总比较次数(n - m + 1) * m
在多数情况下m远小于n,因此算法运行时间为O(n*m)

低效原因:算法在字符比较不相等时,需要回溯(即i = i - j + 1):即退到s中的下一个字符开始进行继续匹配。


模式匹配的一种改进算法KMP算法:
相对BF算法有较大改进:每当一趟匹配过程出现字符不相等时,主串指示器i不用回溯,而是利用已经得到的"部分匹配"结果,将模式串向右"滑动"尽可能远的一段距离后,进行比较

KMP算法就是一种基于分析模式串P蕴含信息的改进算法

KMP算法思想:
若一趟匹配过程比对失配,在做下一趟匹配比对时,目标S的检测指针不回退,模式P右移,与S的检测指针对齐,再开始比对过程
算法的时间代价:
若每趟第一个不匹配,比较n - m + 1趟,总比较次数最坏达到(n - m) + m = n;
若每趟第m个不匹配,总比较次数最坏亦达到n

if S(s)S(s + 1)S(S + 2)...S(s+j-1) = P0 P1 P2 ... Pj - 1
if                           P0 P1 ... Pj-2 != P1 P2 ... Pj - 1
=>                         P0 P1 ... Pj-2 != S(s + 1) S(s + 2) ... S(s + j - 1)

=>        下一趟一定不匹配

if				 P0 P1 ... Pj - 3 != P2 P3 ... Pj - 1

则下一趟也不匹配,因为有

				 P0 P1 ... Pj - 3 != S(s + 2) S(s + 3) ... S(s + j - 1)


知道对于某一个k值,使得

			    	 P0 P1 ... Pk + 1 != P(j - k - 2) P(j - k - 1) ... P(j - 1)
且			     	    P0 P1 ... Pk = P(j - k - 1) P(j - K) ... P(j - 1)

则                         P0 P1 ... Pk = S(s + j - k - 1) S(s + j - k) ... S(s + j - 1)
						   		                 = P(j - k + 1)     P(j - k)     ... P(j - 1)
						   		                 
== >     下一趟可以直接用P(k + 1)与S(s + j)继续比较
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

噶米困了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值