当前位置: 首页 > article >正文

数据结构(邓俊辉)学习笔记】串 16——Karp-Rabin算法:串即是数

文章目录

  • 1. 化串为数
  • 2. 凡物皆数
  • 3. 亦是数

1. 化串为数

在这里插入图片描述

接下来的这节,我们再来讨论一种十分另类的串匹配算法,也就是所谓的 Karp-Rabin 算法。回顾此前所介绍的几种串匹配算法,我们所面临的难题是一样的。也就是说在这里,我们每次比较的对象不再是单个字符,而是由一系列的字符所构成的串或者子串。因此,如果局部子串的长度为 m,那么对于所有的 n 个潜在的对齐位置,我们在最坏情况下都可能需要执行 m 次比对,因此在 最坏情况下,我们往往必须付出如此之高的代价。

那么,能否从中自然地剔除掉这个因子 m 呢?我们马上就会看到一种别致的方法,也就是将每一个串视作为一个数。正确切地讲,应该是整数。不难理解,果真若能实现这种转换,那么任何两个串之间的比较,都相当于整数之间的比较,从而我们只需花费常数的时间,也就是说与字符串的长度无关。那么这些美好的设想能够实现吗?答案是能够。

实际上,不少前贤先哲都已经指出,包括串在内的万事万物,其实本质上讲都是数,或者确切地讲是整数。没错,整数。它们才是自然的本源。

2. 凡物皆数

在这里插入图片描述

是的,凡物皆数。关于自然的本源,这是很多人所秉持的一种信念,在我看来,其中最坚定的信奉者,同时也是最高明的实践者,莫过于哥德尔。比如,为了证明伟大的不完备定理,他发明了一种简洁而强大的编号方式,来对逻辑系统中几乎所有的组成部分统一以自然数来做标识,这种编号是基于素数序列来完成的。

我们知道,素数虽然是无限的,但同时也是可数的。因此,我们可以用 p(k) 来指代第 k 个素数,比如前几个都众所周知,首先是2,第二个是3,第三个是5,第四个为7以及第五个是11,诸如此类。

那么哥德尔敏锐地发现,任何一个有限维度的自然数向量,按照某种法则都会唯一的对应于某个自然数

比如,我们考察这样一个有整数构成的 8 维向量,它的各个分量依次为3 1 4 1 5 9 2 6。我们现在来找出它所对应的那个自然数。既然是 8 维,所以我们首先要搬出前 8 个素数,也就是 2 3 5 7 11 13 17 19,这 8 个素数将分别与向量的 8 个分量一 一配对。
  ~  
第 1 个分量为3,所以我们相应地将它转换为第一个素数,2 的 3+1 也就是4次方;第 2 个分量为 1,所以我们也将它转化为第二个素数 3的 1+1,也就是2次方;第 3 个分量是4,所以我们也将它转化为第三个素数 5 的 4 + 1,也就是5次方;以下依次类推。我可以得到第 4 个素数的 1+1 次方,第 5 个素数的 5+1 次方,第 6 个素数的9+1次方,第 7 个素数的 2+1 次方,以及最后第 8 个素数的 6+1 次方。

显然,这 8 个因子的乘积依然应该是一个自然数。也就是说,如此我们的确可以将任何一个向量转化为一个自然数。而这种转换方法还具有一个更为精妙、更为神奇的特征,根据如此得出的一个自然数,我们还可以反过来忠实地还原此前的向量

我想,点破了这层窗户纸之后,你应该能够独立地看出这种还原的方法,对吧?

3. 亦是数

在这里插入图片描述

既然万事万物的本源都对应于自然数,那么串也自然应该对应于数。接下来我们就来看看这句话如何兑现。

首先来考虑一种我们最为熟悉的串,也就是由十进制数字所构成的串。比如,由阿拉伯数字所构成的这样一个串。如果我要说这个串是一个自然数,我想你不会有任何异议的,没错,这就是我们最常用的技术方法,那么一般的串呢?

应该还记得我们的约定,组成字符串的每一个字符都来自于事先约定的某个字母表,而在这里,字母表的规模又是至关重要的。如果将它记作 d,那么字母表中的所有字符也就可以按照任何一种次序,与0到 d -1 之间的整数一 一对应了。于是,基于这个字母表所建立起来的任何一个字符串都可以视作为一个 d 进制的自然数。

不妨考察,以26个大写英文字母所构成的字符集,于是,由大写字母所构成的任何一个英文单词也必然对应于某个 26 进制的自然数。
  ~  
比如在单词 cat 中,c 对应的编号为2,a 对应于0,而 t 对应于19。如果你关心这个数字的具体数值,不妨借用一下我们在第4章所给出的进制转换算法。

不过这个方法还存在一点小小的瑕疵,好在修补这个瑕疵并不困难,这个任务不妨由你独立地来完成(上图已经给出方法)。

既然每一个串都可以对应于一个自然数,那么接下来很自然的一个模式串在某个主串中能够出现,仅当这个子串在数值上与模式串相当。

请注意,经过这样的视角转换,我们已经在无形中将串与串的比对,转化为了整数与整数的比对, 也就是说,串与串之间的比对将有望在常数的时间内完成。

果真如此,以上也就自然给出了一个串匹配的算法。的确如此,我们已经朝着这个方向迈出了最重要的一步,尽管我们还需要做更多细致的工作。


http://www.kler.cn/a/291470.html

相关文章:

  • leetcode:344. 反转字符串(python3解法)
  • python调用MySql保姆级教程(包会的)
  • 20241116解决在WIN11和ubuntu20.04通过samba共享时出现局域网千兆带宽拉满的情况
  • FastAPI 中间件详解:实现高性能 Web 应用的完整指南和实际案例
  • 4A架构之间的关系和集成
  • 深挖C++赋值
  • 9:00面试,9:08就出来了,问的问题有点变态。。。
  • 九、制作卡牌预制体
  • 【深度学习】yolov8的微调
  • Android framework 编程之 - Binder调用方UID
  • CSS基础 --- % 相对于谁
  • 斯坦福UE4 C++课学习补充21:击败动画
  • Snipaste:一款强大的截图与贴图工具
  • 汽车电子行业知识:什么是车辆定位技术
  • UNIX及UNIX-like环境下的调试工具gdb使用方法
  • 【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
  • ES之三:springboot集成ES
  • Django+Vue家居全屋定制系统的设计与实现
  • chapter09-OOP高级部分——(单例模式)——day12
  • 【图灵完备 Turing Complete】游戏经验攻略分享 Part.3 存储器
  • Spring Boot如何解决跨域问题?
  • 区块链开发解决方案有哪些
  • 高防IP的作用有哪些?
  • 羲和能源大数据平台——Python数据绘图方法
  • 前端XSS 攻击与SQL注入 处理
  • 本地电脑交叉编译ffmpeg 到 windows on arm64