字符串匹配Sunday算法C++实现

61 篇文章 0 订阅
61 篇文章 0 订阅

字符串匹配Sunday算法

sunday算法简介

Sunday算法是Daniel M.Sunday于1990年提出的一种比BM算法搜索速度更快的算法。其核心思想是:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率(算法思想很简单)。在一定程度上比KMP算法和BM算法更优。但是该算法最坏情况下的时间复杂度为O(m*n)。 
Sunday的算法思想和Horspool有些相似,但是。当出现不匹配的时候,却不是去找匹配串中不匹配的字符在模式串的位置,而是直接找最右边对齐的右一位的那个字符在模式串的位置。

sunday算法原理

这里写图片描述 
举个栗子:设字符串为 THIS IS A SIMPLE EXAMPLE,搜索词为EXAMPLE如图所示。 
1.这里写图片描述 
第一次匹配过程中,从搜索词的首字母开始从左往右匹配,字符串中的“H”与 “E”发现不匹配,就查找字符串中右端对齐的字符的下一位,也就是“ ”(空格),原则:如果该字符没有在匹配串中出现则直接跳过,即移动步长= 匹配串长度+1;否则,同BM算法一样其移动步长=匹配串中最右端的该字符到末尾的距离+1。

2.这里写图片描述 
发现字符串与搜索词右端对齐的下一位字符即“ ”(空格)并不在搜索词中出现过,就移动步长为8位,如图所示。

3.这里写图片描述 
继续从左往右开始匹配字符,发现字符串中的“A”与搜索词中的“E”并不匹配,就查看右端对齐的下一个字符“E”,发现“E”在搜索词中,并且有两个,按照suanday原则就选择搜索词中最右的字符“E”,这样可以保证在右端对齐的下以一个字符在搜索词中存在的情况下,移动步长最小,保证这种情况下不失匹配机会。 
移动后,从左往右开始匹配,发现是“ ”(空格)与搜索词的首字母“E”不匹配,继续按上述匹配原则进行移动。 
4. 
这里写图片描述 
字符串与搜索词最右端的下一个字符是“ ”(空格),依照上述原则,在搜索词中并不存在“ ”(空格),移动的步长为8,最终结果如图所示。

总结:

(1) 开始左对齐,从左向右依次比较,直到遇到不同的字符;

(2) 匹配字符串后移一位,然后直接比较匹配字符串的最后的一个字符,并作出相应的对其调整(类似KMP的);

(3) 调整后再从头从左向右比较。

下面是我写的代码:

int indexPost(const string s, const char ch) {
	int k1(s.length() - 1);
	while (k1 >= 0 && s[k1] != ch) --k1;
	return k1;
}

vector<int> sunday(const string s1, const string s2) {
	vector<int> ret;
	int sl1(s1.length()), sl2(s2.length());
	if (!(sl1 && sl2))return ret;
	for (int k1(0), k2(0); k1 < sl1;) {
		if (s1[k1] == s2[k2]) ++k1, ++k2;
		else {
			k1 += sl2 - k2;
			k1 -= k1 < sl1 ? indexPost(s2, s1[k1]) : 0;
			k2 = 0;
		}
		if (k2 == sl2) ret.push_back(k1 - k2), k1 -= k2 - 1, k2 = 0;
	}
	return ret;
}









  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值