Sunday 算法介绍

news2025/1/10 23:28:51

1. Sunday 算法介绍

「Sunday 算法」 是一种在字符串中查找子串的算法,是 Daniel M.Sunday 于1990年提出的字符串模式匹配算法。

Sunday 算法思想:对于给定文本串 T 与模式串 p,先对模式串 p 进行预处理。然后在匹配的过程中,当发现文本串 T 的某个字符与模式串 p 不匹配的时候,根据启发策略,能够尽可能的跳过一些无法匹配的情况,将模式串多向后滑动几位。

Sunday 算法思想跟 Boyer Moore 算法思想类似。不同的是,Sunday 算法匹配顺序是从左向右,并且在模式串 p 匹配失败时关注的是文本串 T 中参加匹配的末尾字符的下一位字符。当文本串 T 中某个字符跟模式串 p 的某个字符不匹配时,可以将模式串 p 快速向右移动。

遇到不匹配字符时,可以根据以下两种情况向右快速进行移动:

  • 情况 1:文本串 T 中与模式串 p 尾部字符 p[m - 1] 对应的字符下一个位置的字符 T[i + m] 出现在模式串 p
    • 这种情况下,可将T[i + m] 与模式串中最后一次出现的该字符对齐,如下图所示。
    • 向右移动位数 = 文本串 T 中与模式串 p 尾部位置的下一个位置 - T[i + m] 在模式串中最后一次出现的位置
    • 注意:文本串 T 中与模式串 p 尾部位置的下一个位置其实就是「模式串长度」。

  • 情况 2:文本串 T 中与模式串 p 尾部字符 p[m - 1] 对应的字符下一个位置的字符 T[i + m] 没有出现在模式串 p
    • 这种情况下,可将模式串整个右移,如下图所示。
    • 向右移动位数 = 整个模式串长度 + 1

2. Sunday 算法步骤

整个 Horspool 算法步骤描述如下:

  • 计算出文本串 T 的长度为 n,模式串 p 的长度为 m
  • 先对模式串 p 进行预处理,生成后移位数表 bc_table
  • 将模式串 p 的头部与文本串 T 对齐,将 i 指向文本串开始位置,即 i = 0j 指向模式串开始,即 j = 0,然后从模式串开始位置开始比较。
    • 如果文本串对应位置的字符 T[i + j] 与模式串对应字符 p[j] 相同,则继续比较后一位字符。
      • 如果模式串全部匹配完毕,则返回模式串 p 在文本串中的开始位置 i
    • 如果文本串对应位置的字符 T[i + j] 与模式串对应字符 p[j] 不同,则:
      • 根据后移位数表 bc_table 和模式串末尾位置对应的文本串上的字符 T[i + m] ,计算出可移动距离 bc_table[T[i + m]],然后将模式串进行后移。
  • 如果移动到末尾也没有找到匹配情况,则返回 -1

3. Sunday 算法代码实现

3.1 后移位数表代码实现

生成后移位数表的代码实现比较简单,跟 Horspool 算法中生成后移位数表的代码差不多。具体步骤如下:

  • 使用一个哈希表 bc_tablebc_table[bad_char] 表示表示遇到坏字符可以向右移动的距离。
  • 遍历模式串,以当前字符 p[i] 为键,可以向右移动的距离(m - i)为值存入字典中。如果出现重复字符,则新的位置下标值会将之前存放的值覆盖掉。这样哈希表中存放的就是该字符在模式串中出现最右侧位置上的可向右移动的距离。

如果在 Sunday 算法的匹配过程中,如果 T[i + m] 不在 bc_table 中时,可令其为 m + 1,表示可以将模式串整个右移到上一次匹配末尾后边两个位置上。如果 T[i + m]bc_table 中时,可移动距离就是 bc_table[T[i + m]] 。这样就能计算出可以向右移动的位数了。

生成后移位数表的代码如下:

# 生成后移位数表
# bc_table[bad_char] 表示遇到坏字符可以向右移动的距离
def generateBadCharTable(p: str):
    m = len(p)
    bc_table = dict()
    
    for i in range(m):                      # 迭代到最后一个位置 m - 1
        bc_table[p[i]] = m - i              # 更新遇到坏字符可向右移动的距离
    return bc_table

3.2 Sunday 算法整体代码实现

# sunday 算法,T 为文本串,p 为模式串
def sunday(T: str, p: str) -> int:
    n, m = len(T), len(p)
    
    bc_table = generateBadCharTable(p)          # 生成后移位数表
    
    i = 0
    while i <= n - m:
        j = 0
        if T[i: i + m] == p:
            return i                            # 匹配完成,返回模式串 p 在文本串 T 的位置
        if i + m >= n:
            return -1
        i += bc_table.get(T[i + m], m + 1)      # 通过后移位数表,向右进行进行快速移动
    return -1                                   # 匹配失败

# 生成后移位数表
# bc_table[bad_char] 表示遇到坏字符可以向右移动的距离
def generateBadCharTable(p: str):
    m = len(p)
    bc_table = dict()
    
    for i in range(m):                      # 迭代到最后一个位置 m - 1
        bc_table[p[i]] = m - i              # 更新遇到坏字符可向右移动的距离
    return bc_table

print(sunday("abbcfdddbddcaddebc", "aaaaa"))
print(sunday("abbcfdddbddcaddebc", "bcf"))

4. Sunday 算法分析

  • Sunday 算法在平均情况下的时间复杂度为 O ( n ) O(n) O(n),但是在最坏情况下时间复杂度会退化为 O ( n ∗ m ) O(n * m) O(nm)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1520304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spy分析文件另存为弹框【selenium】

有时需要下载多个文件&#xff0c;但是不想保存在同一个目录下&#xff0c;需要做两步 selenium设置浏览器默认下载路径&#xff0c;这个路径需要是个不存在的路径操作文件另存为弹框 文章目录 selenium设置浏览器默认下载路径操作文件另存为弹框 selenium设置浏览器默认下载路…

Golang中map数据结构字段解析

Golang里map底层数据结构具体如下图所示&#xff1a; map其实就是一个指向 hmap 的指针&#xff0c;占用了8个字节 hmap各自段存放的字段意义如下&#xff1a; 字段含义countmap中元素的个数&#xff0c;对应len (map)的值flags状态标志位&#xff0c;标记map的一些状态B桶数…

MySQL大小写敏感、MySQL设置字段大小写敏感

文章目录 一、MySQL大小写敏感规则二、设置数据库及表名大小写敏感2.1、查询库名及表名是否大小写敏感2.2、修改库名及表名大小写敏感 三、MySQL列名大小写不敏感四、lower_case_table_name与校对规则4.1、验证校对规则影响大小写敏感4.1、验证校对规则影响排序 五、设置字段内…

FPGA静态时序分析与约束(三)、读懂vivado时序报告

系列文章目录 FPGA静态时序分析与约束&#xff08;一&#xff09;、理解亚稳态 FPGA静态时序分析与约束&#xff08;二&#xff09;、时序分析 文章目录 系列文章目录前言一、时序分析回顾二、打开vivado任意工程2.1 工程布局路由成功后&#xff0c;点击vivado左侧**IMPLEMENT…

SpringMVC 02

这里先附上前一篇的地址,以上系列均为博主的学习路线,仅供参考 初识Spring MVC-CSDN博客 下面我们从SpringMVC传递数组开始讲起 1.传递数组 传递数组的方式和传递普通变量的方式其实是相同的,下面我们附上传递的图片 RequestMapping("/r7")public String r1(String[…

【Git】本地仓库关联远程仓库

Git 本地项目关联远程仓库 本地 本地已有项目 ● 项目 07.GitLocalTest 包含有一个js ○ test.js 远程仓库 ● 远程仓库地址 ○ https://github.com/Sonnenlicht77/gitTest.git ○ 仓库只有一个 readme.md 关联 1.本地 1.1 本地仓库 ● git init ● git add . ● gi…

考研复习C语言进阶(3)

结构体 1 结构体的声明 1.1 结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.2 结构的声明 struct tag { member-list; }variable-list; 例如描述一个学生&#xff1a; struct Stu { char name[20];//名字 int ag…

Java开发从入门到精通(九):Java的面向对象OOP:成员变量、成员方法、类变量、类方法、代码块、单例设计模式

Java大数据开发和安全开发 &#xff08;一)Java的变量和方法1.1 成员变量1.2 成员方法1.3 static关键字1.3.1 static修饰成员变量1.3.1 static修饰成员变量的应用场景1.3.1 static修饰成员方法1.3.1 static修饰成员方法的应用场景1.3.1 static的注意事项1.3.1 static的应用知识…

03-java基础-运算符(数据类型转换)、原码、补码、反码

一、运算符 一、1、算术运算符 在代码中如果有小数参与运算&#xff0c;结果有可能会不精确。 一、1.1、数字相加 一、1.1.1、类型转换的分类&#xff08;2种&#xff09; 一、1.1.1.1、类型转换的分类1-----隐式转换 一、1.1.1.1、类型转换的分类2-----强制转换 一、1.2、字符…

海外媒体宣发套餐推广:如何选择最佳方案-华媒舍

在信息时代&#xff0c;传播和宣传已经成为各个行业发展的关键部分。尤其对于拓展国际市场的企业来说&#xff0c;海外媒体宣发更是至关重要。由于各种原因&#xff0c;很多企业在选择海外媒体宣发套餐时感到困惑。本文将为您介绍如何选择最佳的海外媒体宣发方案。 1.了解目标市…

工匠的发展与兴衰趋势-机器人篇

这是一篇纯纯调侃的博客&#xff0c;如有雷同纯属意外。 之前&#xff0c;写过&#xff1a; 从2050回顾2020&#xff0c;职业规划与技术路径&#xff08;节选&#xff09; 从2050回顾2020&#xff0c;职业规划与技术路径&#xff08;节选&#xff09;补充 未来以“工”为主的…

LarkXR上新了 | Apollo多终端与XR体验的优化创新

作为领先的数字平行世界产品技术提供方&#xff0c;「Paraverse平行云」一直致力于为企业和开发者提供企业级实时云渲染解决方案。其多终端接入产品LarkXR Apollo&#xff0c;基于底层Runtime技术&#xff0c;实现了在Windows、Linux、MacOS、Android、iOS等多种操作系统下&…

centos破解root密码以及如何防止他人破解root密码

目录 破解root密码 服务器重启 1.再重启页面上下选择第一个按e进入内核编辑模式 2.找到linux16开头的一行&#xff0c;光标移动到最后添加 init/bin/sh Ctrlx 保存 3.进入单用户模式 4.重新挂在根分区 5.关闭selinux 6.更新密码 passwd 7.在根分区下面创建一个隐藏文件…

字符串函数(C语言详解)

1.字符串简介 字符串是一串连续的且以\0结尾的字符 char arr[]"zhangsan";//将字符串存到数组里面 char*a"lisi";//常量字符串 char arr1[]{z,h,a,n,g};//字符数组 注意&#xff1a; 1.以第一种形式初始化字符串时&#xff0c;计算机会自动在字符串末尾加…

leetcode-打家劫舍专题系列(动态规划)

198.打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…

C# WPF中设置图标时出现TypeConverterMarkupExtension异常

异常内容为&#xff1a;System.Windows.Baml2006.TypeConverterMarkupExtension 是因为有些地方比如菜单和左上角默认的图标等&#xff0c;只能使用ico格式的文件&#xff0c;如果设置的是png格式的文件&#xff0c;就会出现此错误&#xff01;通过在线转ico的方式把png转换一…

【Maven学习笔记】Maven入门教程(适合新手反复观看学习)

Maven学习笔记 Maven的简要介绍Maven的安装和配置Maven的安装Maven安装的常用配置 Maven的使用入门编写pom编写主代码编写测试代码打包和运行使用Archetype生成项目骨架 Maven核心概念的阐述坐标案例分析依赖依赖的范围传递性依赖依赖范围依赖调节可选依赖Maven依赖常用的技巧 …

《ARM汇编与逆向工程》读书心得与实战体验

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 &#x1f4d8; 一、引言 &#x1f4dd; 二、…

vite打包流程和原理

文章目录 打包原理Vite比Webpack快&#xff1f;在生产环境下的表现启动项目后&#xff0c;完成加载比较慢&#xff1f;Esbuild & Rollup热更新 打包原理 vite利用了ES module这个特性&#xff0c;使用vite运行项目时&#xff0c;首先会用esbuild进行预构建&#xff0c;将所…