Sunday 算法详解
Sunday 算法
Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配。其核心思想是:在匹配过程中,模式串发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率。
一、匹配机制
匹配机制非常容易理解:
- 目标字符串
String
- 模式串
Pattern
- 当前查询索引
idx
(初始为 0) - 待匹配字符串
str_cut
:String [ idx : idx + len(Pattern) ]
每次匹配都会从 目标字符串中 提取 待匹配字符串 与 模式串 进行匹配:
- 若匹配,则返回当前
idx
- 不匹配,则查看 待匹配字符串 的后一位字符
c
:- 若
c
存在于Pattern
中,则idx = idx + 偏移表[c]
- 否则,
idx = idx + len(pattern)
- 若
循环上述匹配过程直到 idx + len(pattern) > len(String)
二、偏移表
偏移表的作用是存储每一个在 模式串 中出现的字符,在 模式串 中出现的最右位置到尾部的距离 +1,例如 aab:
- a 的偏移位就是
len(pattern)-1 = 2
- b 的偏移位就是
len(pattern)-2 = 1
- 其他的均为
len(pattern)+1 = 4
综合一下:
shift[w]={m−max{i<m∣p[i]=w}if w is in P[0..m-1]m+1otherwiseshift[w] = \begin{cases}m-max\{i<m|p[i]=w\}\quad \text {if w is in P[0..m-1]} \\ m+1\quad \text{otherwise} \end{cases} shift[w]={m−max{i<m∣p[i]=w}if w is in P[0..m-1]m+1otherwise
三、举例
String: checkthisout
Pattern: this
Step 1:
- idx = 0
- 待匹配字符串为:
chec
- 因为
chec != this
- 所以查看
chec
的下一个字符k
k
不在 Pattern 里- 所以查看 偏移表,
idx = idx + 5
Step 2:
- idx = 5
- 待匹配字符串为:
this
- 因为
this == this
- 匹配,所以返回 5
四、算法分析
时间复杂度: 最坏情况 O(nm)O(nm)O(nm) ,平均情况 O(n)O(n)O(n)
空间复杂度: O(c)O(c)O(c),c为位移表长度
五、代码实现
class Solution:def strStr(self, haystack, needle):haystack_length = len(haystack)needle_length = len(needle)return self.sunday(haystack, haystack_length, needle, needle_length)def sunday(self, s, s_len, p, p_len):bc_move_dict = self.badChatMove(p, p_len)now = 0# 如果匹配字符的位置到达两字符串长度的差值,则不可能存在匹配字串,则退出循环while now <= s_len - p_len:# 比对当前位置的子串是否和模式串匹配if s[now: now+p_len] == p:return now# 如果以及到达两字符串长度的差值,那么这将是最后一个可能匹配到的子串# 经过上面的比对没有匹配的话,直接返回-1if now == s_len - p_len:return -1# 更新下标,如果模式串不包含匹配串后面的第一个字符,则移动 p_len+1 个位数now += bc_move_dict.get(s[now+p_len], p_len+1)return -1# 坏字符移动数量计算def badChatMove(self, p, p_len):bc_move_dict = dict()for i in range(p_len):# 记录该字符在模式串中出现的最右位置到尾部的距离+1bc_move_dict[p[i]] = p_len - ireturn bc_move_dict
参考文章
<<Sunday 解法>>
Sunday 算法详解相关推荐
- Sunday算法详解
一:背景 Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配.其效率在匹配随机的字符串时比其他匹配算法还要更快.Sunday算法的实现可比KMP,BM的实现容易太多. 二 ...
- Matlab人脸检测算法详解
这是一个Matlab人脸检测算法详解 前言 人脸检测结果 算法详解 源代码解析 所调用函数解析 bwlabel(BW,n) regionprops rectangle 总结 前言 目前主流的人脸检测与 ...
- 图论-最短路Dijkstra算法详解超详 有图解
整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...
- C++中的STL算法详解
1.STL算法详解 STL提供能在各种容器中通用的算法(大约有70种),如插入.删除.查找.排序等.算法就是函数模板,算法通过迭代器来操纵容器中的元素.许多算法操作的是容器上的一个区间(也可以是整个容 ...
- 粒子群(pso)算法详解matlab代码,粒子群(pso)算法详解matlab代码
粒子群(pso)算法详解matlab代码 (1)---- 一.粒子群算法的历史 粒子群算法源于复杂适应系统(Complex Adaptive System,CAS).CAS理论于1994年正式提出,C ...
- 基础排序算法详解与优化
文章图片存储在GitHub,网速不佳的朋友,请看<基础排序算法详解与优化> 或者 来我的技术小站 godbmw.com 1. 谈谈基础排序 常见的基础排序有选择排序.冒泡排序和插入排序.众 ...
- 目标检测 RCNN算法详解
原文:http://blog.csdn.net/shenxiaolu1984/article/details/51066975 [目标检测]RCNN算法详解 Girshick, Ross, et al ...
- Twitter-Snowflake,64位自增ID算法详解
Twitter-Snowflake,64位自增ID算法详解 from: http://www.lanindex.com/twitter-snowflake%EF%BC%8C64%E4%BD%8D%E8 ...
- 数据结构与算法详解目录
数据结构与算法详解是一本以实例和实践为主的图书,主要是经典的数据结构与常见算法案例,来自历年考研.软考等考题,有算法思路和完整的代码,最后提供了C语言调试技术的方法. 后续配套微课视频. 第0章 基 ...
最新文章
- Go 知识点(14) — Go 多协程(单个协程触发panic会导致其它所有协程挂掉,每个协程只能捕获到自己的 panic 不能捕获其它协程)
- mysql查询语句在哪里编写_mysql编写语句:更新查询
- 团体程序设计天梯赛-练习集 L1-002 打印沙漏
- 使用Chrome的inspect element注意事项
- SVN:This client is too old to work with working copy…解决方法
- AIX配置Volumn
- JS中元素的属性(class、style)操作
- android ril移植,Quectel_Android_RIL_SR01A40V36 EC20安卓移植资料和相关代码 - 下载 - 搜珍网...
- 【渝粤题库】陕西师范大学500901 基础物理专题(力、热) 作业(专升本)
- Ubuntu16.04+ ROS kinetic 使用kinect2 ORK功能包 linemod算法实现可乐罐识别
- Qt QLineEdit QLabel 添加clicked事件
- [netplus]初见,Netplus快速开始之PingPong Example
- RAKsmart:Linux SSH 客户端断开后保持进程继续运行配置方法
- Spring AOP实现原理,从代理说起
- 电角速度和机械角速度
- 从零开始学数据分析之——《线性代数》第三章 n维向量
- matlab绘制四棱台,几何画板绘制正四棱台的图文教程
- UE4的JSON读写方式二
- 614717-89-4|2-(4-溴苯基)咪唑[4,5f][1,10]邻菲啰啉|分子量:375.22|分子式:C19H11BrN4
- 找不到模块“axios”或其相应的类型声明(vite)