字符串匹配--KMP算法

最近学了一下KMP匹配算法,这个算法在字符串匹配中还是很有名的

一般的字符串匹配算法是这样的

1.比较目标串和待匹配的字符串,一个字符一个字符的比较,如果比较到待匹配串的末尾,则返回匹配成功的位置;

2.发现有不同的停止比较,将目标串向后移动一格,待匹配字符串重新回到起点,回到步骤1,继续匹配。

这个算法的优点是思路简单,有点像排序中的冒泡排序,选择排序的样子。缺点就是有大量的重复计算。


KMP匹配算法就是为了实现减少不必要的重复计算,这个思想在很多改良的算法中都是通用的。

        例如 要寻找 pappappar 中pappar 出现的位置,按照上面的算法第一次匹配中一直匹配到pappar中的 ‘r’才发现匹配不成功,于是从待查串计数器移到‘a’ 的上面,目标串重新回到开始,继续匹配。这里重复匹配就出现了,可以看到在目标串 ‘r’ 前面有pa 是和自己前面是一样的,也就是说,下次匹配可以从第三位p和目标串中的第三个位置开始比较,如下图


这样就达到了待测串中遍历器不用回溯,目标串的遍历器也减少回溯的目的,实现如下

int * Cal(char * str,int length)  //计算模式串
{
	int* mod=new int[length];
	mod[0]=mod[1]=0;
	for(int i=2;i<length;i++)
		if(str[i-1]==str[mod[i-1]])
			mod[i]=mod[i-1]+1;
		else if(str[i-1]==str[0])
			mod[i]=1;
		else 
			mod[i]=0;
		for(int i=0;i<length;i++)
			cout<<mod[i]<<" ";
		cout<<endl;
		return mod;
}
int KMP(char *target,char *source,int tlength,int slength)
{
	int *mod=Cal(target,tlength);
	int tar=0,sour=0;  
	if(target==NULL||source==NULL||tlength<0||slength<0)
	{
		cout<<"参数不合法"<<endl;
		return -1;
	}
	while(sour<slength)
	{
		if(source[sour]==target[tar])
		{
			sour++;
			tar++;
			if(tar==tlength)
			{
				cout<<"位置"<<sour-tlength<<"检测到目标串"<<endl;
				tar=0;
			}
		}
		else if(mod[tar]==0)  //如果该位置之前的串的后缀和其前缀不同
		{
			sour++;
			tar=0;
		}
		else 
			tar=mod[tar];   //如果该位置之前的串的后缀和其前缀相同,利用该信息

	}
	cout<<"检测完毕"<<endl;
	return 1;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值