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

数据结构(邓俊辉)学习笔记】串 14——BM_GS算法:构造gs表

以下,就来简要地介绍 gs 表的具体构造算法。算法为了便于理解其原理,这里将整个算法划分为若干的层次,并逐层递进、逐层细化。
在这里插入图片描述

我们首先需要引入 MS 子串与 ss 表的概念。实际上,相对于模式串中的任何一个字符 P[j] ,所谓的 MS[j] ,就是某个以 P[j] 为末字符的子串。而且这个子串也同样会出现于整个模式串的尾部。

当然,如果同时存在多个这样的候选,我们会在其中选择最长的那个。概括而言,所谓的 MS[j] 就是终止于 P[j] ,同时与全串的后缀实现最长匹配的子串。当然,这个子串也有可能是空。我们来看这样一个实例:

对于P[8],也就是字符 E 而言,它所对应的 MS 子串,自右向左由 E、C、I、R 这四个字符组成,因为这个子串与整个模式串的后缀实现了最长的匹配。

相应的,在 ss 表中,j 所对应的那一项,其实也就是 MS[j] 子串的长度。

在刚才这个例子中,8号字符 E 所对应的 ss 表项,也自然就应该是子串 RICE 的长度,4。
  ~  
同理,对于字符 P[2] 而言,它所对应地MS 子串为ICE 。相应地ss表项,也就是这个串的长度,3。

在这里插入图片描述

实际上,在中转的这个 ss 表中,已经蕴含了我们最终要计算的 gs 表的所有信息。因此,快速构造 gs 表的问题,也就自然地转化为了如何快速地构造 ss 表。

那么,通过 ss 表,具体的如何构造出最终的 gs 表呢?无非两种情况:

  1. 首先, ss[j] 可能达到最大的极限,也就是 j +1。此时情况如这个图所示(上图中上面那个图),也就说 MS[j] 子串足够长,以至于它就是整个模式串的一个前缀。于是对于这个范围内的任何一个字符P[i], 一旦在扫描比对中发生失配,m-j-1 也必然是一个值得考虑的位移距离。
  2. 此外,都是一般的情况。也就是 MS[j] 子串的长度,充其量不过 j 。此时的情况可以由下面这幅图来示意。可以看到此时的 MS[j] 子串长度还没有达到极限。于是如果将来在扫描比对的过程中,在这个位置处(m - ss[j] - 1)发生首次适配,接下来一种值得考虑的位移距离自然也是 m-j-1。

通过以上的分析可以看到,构造 gs 表,关键就在于如何构造出 ss 表。当然,根据以上定义,即便采用蛮力策略也是可以构造出这个表的。

然而很遗憾,我们为此需要平方量级的时间。那么这个结果能否改进呢?当然是肯定的,采用新的算法,我们只需线性的时间就足以构造出 gs 表。


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

相关文章:

  • [Linux]多线程详解
  • sql注入之二次注入(sqlilabs-less24)
  • Python习题 250:删除空文件夹
  • 初识Linux · 共享内存
  • H5页面多个视频如何只同时播放一个?
  • 机器学习-35-提取时间序列信号的特征
  • Linux文件和目录常用命令
  • 探索OpenCV:图像处理基础与实践
  • 基于STM32开发的智能灌溉系统
  • day31-测试之性能测试工具JMeter的功能概要、元件作用域和执行顺序
  • python基础(13魔法方法介绍)
  • Axure原型设计技巧与设计经验分享
  • 我的docker随笔44:构建nginx镜像
  • 揭示灵活分布式云平台的速效降本之道
  • CSS 的超级好用的object-fit属性
  • git服务搭建
  • tomcat实验
  • 小程序组件生命周期和获取组件实例
  • 「Python程序设计」基本数据类型:列表(数组)
  • 理解数据库系统的内部结构
  • UE5-----Niagara粒子系统
  • 10080-0-监测文件夹并解压压缩包-支持zip-rar-7z压缩包的解压-不支持子文件夹/密码/多层嵌套压缩包解压-UI
  • 在Linux下搭建go环境
  • 设计模式-常见的设计原则或最佳实践
  • 【RNN】循环神经网络RNN学习笔记
  • FaceFormer嘴形同步论文复现