基本算法之字符串匹配算法Sunday

int sundaySearch(const char *mainStr,const char *subStr)
{
	if(mainStr==NULL || subStr==NULL)
		return -1;
	int mainStrLen=strlen(mainStr);
	int subStrLen=strlen(subStr);
	if(subStrLen>mainStrLen)
		return -1;

	int main_i=0;
	int sub_j=0;

	//设定每个字符最右移动步长,保存每个字符的移动步长
	//如果大串中匹配字符的右侧一个字符没在子串中,大串移动步长= 整个串的距离 +1
	//如果大串中匹配范围内的右侧一个字符在子串中,大串移动距离= 子串长度 - 这个字符在子串中的位置     
        //若已知源字符串中当前窗口最右端外部第一个字符,那么窗口向右至少向右移动多少个单位
        //才能使得源字符串当前窗口与目标字符串完全匹配,charStep就是做这个查表工作
	int charStep[256];
	for(int i=0;i<256;i++)
		charStep[i]=subStrLen+1;
	for(int i=0;i<subStrLen;i++)
	{
		// 如果目标字符串中有重复字符,那么自动将最小起跳步数替换原有步数
		charStep[(unsigned char)subStr[i] ]=subStrLen-i;
	}
	

	while(main_i<mainStrLen)
	{                  
		//从main_i开始与目标字符串匹配,tem记录起始位置,如果没有匹配成功,那么将从tem开始起跳
		int tem=main_i;
		while(sub_j<subStrLen)
		{
			if(mainStr[main_i] ==   subStr[sub_j])
			{
				main_i++;
				sub_j++;
				continue;                   
			}                
			else{
				//如果匹配范围外已经找不到右侧第一个字符,则匹配失败
				if(tem+subStrLen > mainStrLen)
					return -1;
				// 计算最少起跳位置
				char firstRightChar=mainStr[tem+subStrLen];
				main_i =tem + charStep[(unsigned char)firstRightChar];
				sub_j=0;   
				break;//退出本次失败匹配 重新一轮匹配
			}  
		}
		if(sub_j == subStrLen)
			return main_i-subStrLen;
	}
	return -1;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值