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

[acm算法学习] 后缀数组SA

学习自B站up主 kouylan 

定义

后缀是包含最后个字母的子串

把字符串 str 的所有后缀按字典排序,sa[i]表示排名为 i 的后缀的开头下标

如何求解SA

倍增的方法

先把每个位置开始的长度为1的子串排序,在此基础上再把长度为2的子串排序(长度为2的子串就 是前面算过的长度为1的子串再加上后面的一位,第 i 位的和 i+1 ),再把长度为4,8,16,32...(两个两个拼)直到串的末尾,也就是排到了后缀。

如何从2^(k-1) 到 2^k

  • 记 rk[i] 表示当前长度下,i 开始的子串的排名
  • 前 2^(k-1) 和后  2^(k-1) 拼成了 2^k
  • 确定  2^k 的排名时,先比较前 2^(k-1)的rk,如果更小,那么整个也更小,不用比后面了;如果前 2^(k-1)相等,则去比较后  2^(k-1) 的rk

up主给的这个图很形象

原串中下标位置为1的a,会去和原串中下标为2的b拼一起,a(1)和a(6)的rk相同,所以比较后面部分,b(2) 比 c(7) 的 rk 要先,所以最后长度为2的 rk 里ab 比 ac 要前。由于c(7)是最后一位了,所以它的下一位是个空串,我们定义空串的rk是-1,这样,因为没有比空串还小的了,设为-1可以达到效果。

求解程序

sa 是根据 rk 来的,根据排序好的 sa 来更新 rk2 (使用临时变量 rk2),因为更新的过程中要用到上一次的 rk ,初始的rk是字典序。

用sort在当前 k 下把 sa 数组排好顺序,然后再遍历一遍数组sa把对应位置的字母排名依次排好。最后更新一遍rk。

重载的排序函数,是根据先比前一半,后比后一半。

时间复杂度 n*log(n)*log(n)

http://www.lryc.cn/news/279625.html

相关文章:

  • DNS解析和它的三个实验
  • [redis] redis的安装,配置与简单操作
  • C++ STL set容器
  • 专业课148,总分410+电子科技大学858信号与系统考研经验电子信息与通信
  • 密码学:一文读懂非对称加密算法 DH、RSA
  • ZooKeeper 实战(二) 命令行操作篇
  • 关于在前台应用路由调用子应用
  • Spring学习 Spring事务控制
  • c++一些使用频率较高的库函数
  • 【从零开始学技术】Fiddler 抓取 https 请求大全
  • 第二百六十四回
  • 用Kimi chat识别并整理图片里面的文字
  • 驾驭未来:从传统运维到智能化运维的转型之路
  • LabVIEW在旋转机械故障诊断中的随机共振增强应用
  • 尚硅谷大数据技术-数据湖Hudi视频教程-笔记02【核心概念(基本概念、数据写、数据读)】
  • 鸿蒙(HarmonyOS)应用开发指南
  • Android 13 辅助屏导航栏不显示问题
  • 【QT】标准对话框
  • 微信小程序跳转方式及问题
  • Redis实现分布式会话
  • AntDesignBlazor示例——暗黑模式
  • 高通平台开发系列讲解(USB篇)adb function代码分析
  • SQL基础知识3
  • GBASE南大通用数据库如何检索单行
  • 【数据结构与算法】单链表(无头单向非循环)
  • C#PDF转Excel
  • vivado xsim 终端 模拟
  • Java并查集设计以及路径压缩实现
  • 【leetcode】力扣算法之删除链表中倒数第n个节点【中等难度】
  • C51--摇头测距小车