【Algorithms 4】算法(第4版)学习笔记 20 - 5.1 字符串排序

news2024/9/22 15:45:24

文章目录

    • 前言
    • 参考目录
    • 学习笔记
      • 1:Java 字符串
      • 1.1:字符串数字类型
      • 2:键索引计数法 key-indexed counting
      • 2.1:排序算法回顾
      • 2.2:关于 key 的假设
      • 2.3:demo 演示
      • 2.4:分析
      • 3:低位优先基数排序 LSD radix sort
      • 3.1:介绍
      • 3.2:证明
      • 3.3:Java 实现
      • 3.4:排序算法小结
      • 4:高位优先基数排序 MSD radix sort
      • 4.1:介绍
      • 4.2:示例
      • 4.3:Java 实现
      • 4.4:潜在风险
      • 4.5:性能
      • 4.6:排序算法小结
      • 5:三向基数快速排序 3-way radix quicksort
      • 5.1:介绍
      • 5.2:Java 实现
      • 5.3:排序算法小结

前言

进入第 5 章《字符串》的学习,本篇主要内容包括:键索引计数法低位优先基数排序高位优先基数排序三向基数快速排序

参考目录

  • B站 普林斯顿大学《Algorithms》视频课
    (请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。)
  • 微信读书《算法(第4版)》
    (本文主要内容来自《5.1 字符串排序》)
  • 官方网站
    (有书本配套的内容以及代码)

学习笔记

注1:下面引用内容如无注明出处,均是书中摘录。
注2:所有 demo 演示均为视频 PPT demo 截图。
注3:如果 PPT 截图中没有翻译,会在下面进行汉化翻译,因为内容比较多,本文不再一一说明。

1:Java 字符串

![L17-51StringSorts_02]

字符串: 字符序列。

重要的基本抽象概念。

  • 基因组序列:在生物信息学中,基因组序列就是由一系列核苷酸(A、T、C、G)组成的字符串,用于描述 DNA 或 RNA 分子的顺序。
  • 信息处理:字符串处理是计算理论和应用的核心部分,涉及文本搜索、替换、格式化、压缩、加密等各种操作。
  • 通信系统:例如在电子邮件系统中,邮件正文、主题以及发件人和收件人的地址都是以字符串形式表示和传输的。
  • 编程系统:在诸如 Java 等编程语言中,字符串是一种核心数据类型,用来存储和操作任意长度的字符序列。

1.1:字符串数字类型

![L17-51StringSorts_05]

字符串数据类型(String Data Type): Java 中不可变字符序列类型。

长度(Length): 计算字符串中字符的数量。
索引(Indexing): 使用索引值访问并获取字符串中的特定位置上的字符。
连接(Concatenation): 将一个字符串与另一个字符串尾部相接合,以生成一个新的合并字符串。

2:键索引计数法 key-indexed counting

2.1:排序算法回顾

![L17-51StringSorts_12]

下界: 对于基于比较的算法,任何算法都需要大约 NlgN 次比较。

Q. 我们是否能够做得更好(尽管存在这个下界限制)?
A. 是的,前提是不依赖于关键键值的直接比较操作。例如,通过利用数组访问一次性做出 R 路选择(而不是每次比较仅做二选一的决定)。

2.2:关于 key 的假设

![L17-51StringSorts_13]

假设: 键是介于 0 和 R-1 之间的整数。
推论: 可以使用键作为数组的索引。

应用举例:
• 按首字母对字符串进行排序。
• 按班级分组对名单进行排序。
• 按区号对电话号码进行排序。
• 用作排序算法中的子程序。

注意: 由于键可能与相关的数据项关联,所以不能仅通过计算每个特定键值的数量来进行处理。

2.3:demo 演示

对应书本章节《5.1.1 键索引计数法》:

  • 5.1.1.1 频率统计
    • 第一步就是使用 int 数组 count[] 计算每个键出现的频率。
  • 5.1.1.2 将频率转换为索引
    • 接下来,我们会使用 count[] 来计算每个键在排序结果中的起始索引位置。
  • 5.1.1.3 数据分类
    • 在将 count[] 数组转换为一张索引表之后,将所有元素(学生)移动到一个辅助数组 aux[] 中以进行排序。
  • 5.1.1.4 回写
    • 因为我们在将元素移动到辅助数组的过程中完成了排序,所以最后一步就是将排序的结果复制回原数组中。

![image-20240321193855166]

目标: 对由 0 到 R - 1 之间的 N 个整数组成的数组 a[] 进行排序。

![image-20240321194248814]

  • 使用键(即数组元素本身)作为索引,统计每个整数出现的频率。

![image-20240321195626740]

  • 计算各整数的频次累积值,以确定它们在排序后的新位置(目的地)。

![image-20240321200959395]

  • 利用键(元素值)作为索引访问频次累积数组,根据累积值将原数组中的元素移动到对应的新位置。

过程说明:a[i] 为原始数组, count[r] 为累积数组,aux[i] 为临时新数组。

依次遍历原始数组,找到累积数组中对应 key 的值作为临时新数组的下标存进去。如:

  • 已知:a[0] = dcount[d] = 6
  • 可得:aux[6] = d
  • 更新:count[d] = 6 + 1 = 7

得到最终结果如下:

![image-20240321200829753]

最终步骤:

![image-20240321201949938]

  • 将排序后的元素复制回原始数组 a[] 中。

2.4:分析

![L17-51StringSorts_19]

命题: 键索引排序所需时间与 N+R 成正比。
命题: 键索引计数法所需的额外存储空间与 N+R 成正比。
稳定?

3:低位优先基数排序 LSD radix sort

3.1:介绍

低位优先的字符串 (基数) 排序 Least-significant-digit-first (LSD) string (radix) sort

![L17-51StringSorts_21]

LSD 字符串(基数)排序。

  • 从右向左考虑字符。
  • 使用第 d 个字符作为键(采用键索引计数法)进行稳定排序。

3.2:证明

![L17-51StringSorts_22]

命题: LSD 排序算法能确保将固定长度的字符串按升序排列。

证明: (通过归纳法对 i 进行证明)
在完成第 i 轮排序后,所有字符串都会依据其最后 i 个字符进行有序排列。

  • 如果两字符串在当前所使用的排序键上不一致,则键索引排序将会把它们按照正确的相对顺序排列好。
  • 如果两字符串在当前排序键上相等,则由于排序算法的稳定性,它们原有的相对顺序会被维持不变。

命题: LSD 排序算法具有稳定性。
证明: 由于键索引计数法具有稳定性,所以 LSD 排序也是稳定的。

3.3:Java 实现

edu.princeton.cs.algs4.LSD

![image-20240321204934941]

edu.princeton.cs.algs4.LSD#sort

![image-20240321205000658]

3.4:排序算法小结

![L17-51StringSorts_24]

4:高位优先基数排序 MSD radix sort

4.1:介绍

高位优先的字符串 (基数) 排序 Most-significant-digit-first (MSD) string (radix) sort

![L17-51StringSorts_32]

4.2:示例

![L17-51StringSorts_33]

对于可变长度字符:

![L17-51StringSorts_34]

将字符串视为在其末尾附加了一个额外的字符(该字符小于任何其他字符)。

C语言字符串: 末尾自动带有额外的字符 '\0',因此无需做额外工作。

4.3:Java 实现

edu.princeton.cs.algs4.MSD

![image-20240321213232883]

edu.princeton.cs.algs4.MSD#sort

![image-20240321213254681]

![image-20240321213311571]

4.4:潜在风险

![L17-51StringSorts_36]

观察1: 对于较小的子数组,该算法极其缓慢。

  • 每次函数调用都需要自己的 count[] 数组。
  • 对于 ASCII 字符集(256 个计数):当 N 等于 2 时,其速度比单纯的复制操作慢大约 100倍。
  • 对于 Unicode 字符集(65536 个计数):当 N 等于 2 时,其速度比单纯的复制操作慢大约 32000 倍。

观察2: 由于递归的原因,会产生大量极小的子数组。

![L17-51StringSorts_37]

解决方案: 针对较小的子数组设置一个阈值转为插入排序。

  • 使用插入排序法,不过是从字符串的第 d 个字符处开始进行排序操作。
  • 实现自定义的 less() 比较函数,确保其在比较时从字符串的第 d 个字符开始。

4.5:性能

![L17-51StringSorts_38]

所检查字符的数量:

  • MSD 只会检查刚好足够对键进行排序所需的字符数。
  • 所需检查的字符数量依赖于具体的键值。
  • 在输入数据量上,检查字符的数量可能会呈现亚线性的时间复杂度特性(基于compareTo() 方法的排序同样也可能具有亚线性时间复杂度特性!)

4.6:排序算法小结

![L17-51StringSorts_39]

5:三向基数快速排序 3-way radix quicksort

5.1:介绍

三向字符串快速排序 3-way string quicksort

![L17-51StringSorts_43]

概述: 在第 d 个字符上执行三向分区操作。

  • 相较于 MSD 字符串排序法中的多路划分,此方法所需额外处理较少。
  • 不会再次检查与分区字符相同的字符(然而对于不等于分区字符的字符仍会进行重新检查)。

![L17-51StringSorts_44]

书中的相关描述:

![image-20240322092319518]

![image-20240322091513800]

5.2:Java 实现

edu.princeton.cs.algs4.Quick3string

![image-20240322091819701]

edu.princeton.cs.algs4.Quick3string#sort

![image-20240322091836319]

![image-20240322091851640]

5.3:排序算法小结

![L17-51StringSorts_48]

对应书本的表格:

![image-20240322094700759]

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

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

相关文章

全球首个Open机器人诞生!当GPT模型有了“肉体”,不仅能听能写还可以干家务!

世界上第一个「ChatGPT机器人」来了!近期,初创公司美国机器人创业公司Figure发布首个基于OpenAI多模态大模型的人型机器人Figure 01。现在直接给LLM造了个身体,具体来说是个OpenAI训练的多模态大模型。 Figure AI发布了一段引人注目的视频&…

计算机硕士,毕业直接后端开发岗,选择C++还是java?

我自己是一名工作多年的C程序员,大学学习的编程语言就是C/C,参加工作后自学了Python、Java、Golang等语言。 现在从事自动驾驶行业的工作,工作中主要使用的编程语言是C和Python。在开始前我有一些资料,是我根据网友给的问题精心整…

外包干了15天,技术退步明显。。。。。

先说一下自己的情况,本科生,2019年我通过校招踏入了南京一家软件公司,开始了我的职业生涯。那时的我,满怀热血和憧憬,期待着在这个行业中闯出一片天地。然而,随着时间的推移,我发现自己逐渐陷入…

力扣热门算法题 59. 螺旋矩阵 II,60. 排列序列,61. 旋转链表

59. 螺旋矩阵 II,60. 排列序列,61. 旋转链表,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.21 可通过leetcode所有测试用例。 目录 59. 螺旋矩阵 II 解题思路 完整代码 Java Python 60. 排列序列 …

蓝桥杯:模拟、枚举

目录 引言一、修剪灌木二、特殊年份三、刷题统计四、日期问题五、六、七、八、九、 引言 本篇文章主要介绍蓝桥杯的模拟和枚举的题目,这种题在 B B B 组还是比较简单的,后续也会一直往里加新的真题,加油! 一、修剪灌木 标签&am…

蓝桥杯算法练习系统—金属采集(树形dp)

问题描述 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了。一些节点之间有道路相连,所有的节点和道路形成了一棵树。一共有 n 个节点,这些节点被编号为 1~n 。人类将 k 个机器人送上了火星&…

消息队列—RabbitMQ如何保证消息可靠性?

1. 如何保证消息的可靠性? 先来看看我们的万年老图,从图上我们大概可以看出来一个消息会经历四个节点,只有保证这四个节点的可靠性才能保证整个系统的可靠性。 生产者发出后保证到达了MQ。MQ收到消息保证分发到了消息对应的Exchange。Exchan…

网络基础(一)初识

1、计算机网络背景 1.1、网络发展 1. 独立模式: 计算机之间相互独立; 2. 网络互联: 多台计算机连接在一起,完成数据共享; 3. 局域网LAN: 计算机数量更多了, 通过交换机和路由器连接在一起; 4. 广域网WAN: 将远隔千里的计算机都连在一起;…

vue3 报错 require is not defined

问题 require is not defined 原因 vite 不支持require的用法, webpack是支持的 解决 方法一: 更改vite使用语法 vite官网 方法二 安装转换插件vite-plugin-require-transform 仓库地址 参考 关于Vite不能使用require问题 方法二Vite 踩坑 —— …

PCL点云处理之最小中值平方(Lmeds法)拟合平面(二百三十四)

PCL点云处理之 最小中值平方法(Lmeds)拟合平面(二百三十四) 一、算法介绍一、拟合原理二、具体实现1.代码2.结果一、算法介绍 (本文提供详细注释,输出拟合平面参数和平面点云) Lmeds(Least Median of Squares)是一种统计学方法,用于拟合数据并减少异常值对拟合结果…

MySQL索引(图文并茂)

目录 一、索引的概念 二、索引的作用 三、创建索引的原则依据 四、索引的分类和创建 1、索引的分类 2、索引的创建 2.1 普通索引 2.1.1 直接创建索引 2.1.2 修改表方式创建 2.1.3 创建表的时候指定索引 2.2 唯一索引 2.2.1 直接创建唯一索引 2.2.2 修改表方式创建 …

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序?

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序? 一、百度搜索找到百度词令小程序 打开手机百度搜索「词令」即可找到百度词令关键词口令直达小程序; 二、百度小程序中心找到百度小程序 2.1、打开手机百度,点击底部我的&a…

SW工具下没有URDF

解决方案,下载

使用Docker搭建YesPlayMusic网易云音乐播放器并发布至公网访问

目录 ⛳️推荐 1. 安装Docker 2. 本地安装部署YesPlayMusic 3. 部署公有云YesPlayMusic播放器 3.1 安装cpolar内网穿透 3.2 固定YesPlayMusic公网地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一…

结构数列递推式的一组严格解

假设一个6*6的平面,这个平面的行和列可以自由的变换。有4点的数列排列为 通过结构加法,在4点和5点结构数列之间变换,迭代10次。 4点数列的顺序为 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 4-1 1 3 2 12 5 6 8 4 …

00后的AI创业风口,优牛企讯揭秘

随着人工智能技术的迅猛发展,AI已经成为创业的新风口,吸引了众多00后年轻人的目光。 他们以敏锐的市场嗅觉和创新精神,积极投身于这片充满无限可能的领域。 在这样一个竞争激烈的背景下,优牛企讯这款企业动态信息监控产品应运而…

三星工厂突发大火···  | 百能云芯

据韩媒报道,三星SDI位于韩国京畿道龙仁市基兴区的器兴工厂发生火灾。火灾发生在当地时间周四下午15:37左右,持续约20分钟后被扑灭。 幸运的是,此次火灾并未造成人员伤亡,但火场附近的一些帐篷已经被烧毁。消防部门目前正在调查火灾…

探索人工智能基础:从概念到应用【文末送书-42】

文章目录 人工智能概念人工智能基础【文末送书-42】 人工智能概念 人工智能(Artificial Intelligence,AI)作为当今科技领域的热门话题,已经深刻地影响着我们的生活和工作。但是,要理解人工智能,我们首先需…

Elastic 被评为 2024 年 Fast Company 最具创新力的公司

近期,Elastic 被《Fast Company》杂志评为 2024 年最具创新力的公司。《Fast Company》认为:作为企业搜索提供商的 Elastic,已将人工智能纳入其技术套件中,以帮助企业快速查找和分析相关企业数据。 这对 Elastic 是一个巨大的荣誉…

一文搞懂Java动态代理:为什么Mybatis Mapper不需要实现类?

在学习Java动态代理之前,我想让大家先思考这样几个问题。 JDK动态代理为什么不能对类进行代理?Mybatis Mapper接口为什么不需要实现类? 如果你还不知道上述问题的答案,那么这篇文章一定能消除你心中的疑惑。喜欢“IT果果日记”文…