首页 > 其他分享 >SAM拾遗碎记

SAM拾遗碎记

时间:2024-07-31 20:30:46浏览次数:6  
标签:子串 前缀 SAM 后缀 扩展 拾遗 endpos sam 碎记

SAM拾遗碎记

SAM是一个非常复杂的算法,相关到很多本质性的问题需要思考,但受限于个人能力,想要完整而系统的写一篇学习笔记,对我来说绝非易事。虽然如此,又不能完全不写点什么,我上次好不容易学完了sam,这次又再一次花了很长的时间,并且还是在之前有所记录的情况下。正是因为sam是如此难的一个算法,每一次新的领悟和理解都是需要一定时间和巧合的,所以我还是选择零碎记下一些关键之处,以备下次学习时能有一些方向和启发。

我之前的博客说,sam是对于有相同endpos的一系列子串做了一个压缩,所以很多功能也建立在endpos相同的子串具有许多相同的性质。这是很有道理的,可以作为sam的一个本质来思考。

sam是一个子串数据结构,每一个子串都能在其中找到对应的表示,子串是连续的,这是一个关键的性质,能够将\(n^2\)的子串数压缩在\(O(n)\)的数据结构中,本质上就是利用了子串连续的性质,当然,如何具体,定量的分析,就是我一直想要搞明白但又还没有的工作了,依然是复用理论中信息复杂度的问题,任重道远啊。

子串,一个特定的子串其实就是一个特定的前缀的特定后缀,这就是sam如何维护所有子串的信息了,sam通过从前往后一个一个的添加字符,从前往后就是所有的前缀, 对于每个前缀,又去维护所有的后缀。

所谓endpos ,其实就是一个子串的出现位置集合,如果两个子串的所有出现位置完全相同,那么其中一个串必然是另一个的后缀。

对于一个endpos,一个字符串出现的所有位置,如果把这些所有的不同位置的相同字符串同时向前扩展一个字符,如果这些扩展的字符都相同, 那么扩展后的字符串都相同,这个字符串有这么一种唯一的向前扩展方式,所以这个字符串在且仅在原来那个endpos中的所有位置出现,所以一个endpos,会覆盖一个字符串区间,直到这个区间中最长的字符串向前扩展时,出现了不同的扩展方式,即不同的扩展字符,这时候就会出现endpos分裂。

endpos构成一颗树, 这个树的所有叶子节点代表一个前缀,因为叶子节点的意思是无法再向前扩展了,只有前缀无法向前扩展,但前缀不一定是叶子节点,因为一个前缀虽然无法再向前扩展了, 但这个子串可能不止在前缀这一个地方出现过,其他非前缀的出现位置仍然可以继续扩展,所以它的分裂出去的endpos大小和会比原来endpos少一个,这一个就是前缀。

简单讲一下如何维护sam把,还是复用的思路,sam的核心是维护后缀link,我们考虑每次往后加入一个新的字符,这时出现了一个新的后缀,如何复用前面的信息来得到这个新的后缀呢?我们考虑这个后缀除了最后一个字符的的子串,也就是前一个后缀,新的后缀可以由前一个后缀向后扩展一个字符得到, 那么我们记录一个ch数组,这个数组用于向后扩展字符,但意义有所不同,这个数组表示的是,严格包含扩展后字符串,且以该串为后缀的,包含且仅包含该串所有出现次数的endpos, 只要这个串之前出现过就会有这么个endpos, 所以你加入新字符后,这个新的最长后缀的某些比较长的子后缀可能是之前没有出现过的,是第一次出现的,所以你要跳跳跳,跳到一个之前出现过的, 但之前出现的所有位置可能都是带着一些更多字符同时出现的,但你现在决定加入的这一个很有可能不顺便带有那些字,符,这就是为什么你要分裂它了。关于构建的部分我就不多讲解了, 这涉及到许多复杂度的问题, 我自己也没搞懂,下次在研究。

我们要维护所有子串的信息,在树上做dp,关键是要包含所有子串,这时正确性的保证,求出endpos出现的所有位置可能是一个具有典型性的问题, endpos其实就是一个后缀,endpos出现的所有位置,其实就是以endpos为后缀的所有子串,也即是所有可能扩展出现的位置,它就等于所有儿子的合并,以及可能存在的本身也代表一个字符串情况, 每一个儿子是每一种扩展,如果这个endpos本身是一个前缀,那么这个不可扩展的前缀要特别记录在当前节点中,这就是一个不重不漏的正确性保证。这个东西或许可以用什么线段树合并来维护。

后缀link构成的那颗树,可以理解为一颗trie树, 是往前加字符的。其实ch,也就是转移, 也可以理解为一个往后加字符的trie树,这就是sam同时支持前后加字符的很好功能,需要注意的是,这个向后的trie树是被压缩的(虽然向前也压缩,但不破坏树结构),这就是为什么它的多个点被压成一个点从而形成了一个dag。

标签:子串,前缀,SAM,后缀,扩展,拾遗,endpos,sam,碎记
From: https://www.cnblogs.com/ltdjcoder/p/18335387

相关文章

  • MySQL存储引擎MyISAM和InnoDB
    目录1.1MySQL存储引擎1.1.1什么是存储引擎1.1.2MySQL5.7支持的引擎1.1.3如何选择MySQL引擎1.1.4可以根据以下的原则来选择MySQL存储引擎 1.1.5MyISAM和InnoDB的区别1.MyISAM存储引擎2.InnoDB存储引擎1.1.6关于MyISAM与InnoDB选择使用1.1.7.修改默认......
  • Meta SAM 2:实时分割图片和视频中对象;Apple Intelligence 首个开发者测试版发布丨 RTE
      开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(Real-TimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑的个人观点,......
  • [个人理解] llama.cpp之sample策略
    最近有点时间看了几天llama.cpp的code,有几个点,想记录一下,不对的地方,欢迎大家指正。话说本该去年就看,奈何这个领域变的太快,索性积累到今年,当openAI也开始挤牙膏的时候一并看了。Summary-llama是跟chatpgt一样,基于transformer架构的decodeonly的一挂,这一系列的模型擅长文字接......
  • samba
    samba简介Samba是在Linux系统上实现SMB(SessionMessageBlock)协议的一个免费软件,以实现文件共享和打印机服务共享安装yum-yinstallsamba配置cat/etc/samba/smb.conf|egrep-v"^#|^$"[global]#指定samba服务器所在的SMB工作组 workgroup=WORKGROU......
  • 杭电多校算法拾遗
    杭电多校算法拾遗树上启发式合并(DSUontree)FromD1T2树题意简述:给定一棵根为1的树,点\(i\)有权值\(A_i\)。对于每个节点\(i\),要求计算:$$ans_i=\sum\limits_{u,v\insubtree(i)}\max(A_u,A_v)\times|A_u-A_v|$$输出\(\mathrm{XOR}_i\(ans_i\\mod{2^{64}......
  • 松灵机器人scout mini小车 自主导航(4)——运行lio-sam建图
    松灵机器人Scoutmini小车运行lio-sam在之前的工作中,我们已经实现了用小车搭载传感器,采用gmapping建图和navigation导航实现小车在2D环境中自主导航,但是实际我们采用的激光雷达多为三维激光雷达。因此决定采用lio-sam来建图。具体操作步骤如下。1.下载雷达仿真1.1下载激光雷达......
  • 安装虚拟机Ubuntu&配置SSH&配置samba&设置公钥
    1安装虚拟机及Ubuntu准备好Vmware16安装包和Ubuntu16.04安装包创建新的虚拟机选择自定义配置选择虚拟机硬件兼容性:默认下一步安装客户机操作系统:选择稍后安装操作系统选择客户机操作系统:选择Linux、Ubuntu64位命名虚拟机:自行修改,可默认下一步处理器配置:根据电脑配......
  • 第三周DAY02---samba、DNS
    1.任务背景公司内网中需要通过域名访问到开发的web应用。获得更好的访问体验。故需要在内网中搭建DNS服务器解析域名,开发、测试、运维人员。可以通过内网DNS服务,访问到公司内部应用。2.任务要求自建dns服务器解析内网域名,能够访问内网web应用www.yuanyu.zhangmin解析到......
  • Samtec技术科普小课堂 | 一文入门射频连接器~
    【摘要/前言】在本文中,我们将回到基础知识,了解一下什么是射频连接器。如果您是信号完整性专家,请点击阅读原文访问我们的网站视频,通过我们的网络研讨会视频了解教科书上可能找不到的知识。如果您是电气工程领域的新手,或者只是需要更好地了解这种产品类型,请继续阅读,本文将通......
  • [Mysql]InnoDB和MyISAM
    InnoDB和MyISAMInnoDB和MyISAM是MySQL数据库系统中最常用的两种存储引擎。它们各自拥有不同的特性和优化点,适用于不同的应用场景。以下是它们之间的一些主要区别:事务支持InnoDB:支持事务(ACID兼容)。它提供了提交、回滚和崩溃恢复功能,非常适合处理大量的短期事务。InnoDB的事务......