定义说明:

后缀:从字符串的任意一个字符开始一直到最后一个字符所构成的一个字符串

例如:对于字符串"abcdefg","cdefg"、"efg"、"g"都是后缀,"cde"则不是后缀

在学习后缀数组之前,我们首先要知道后缀数组是什么?

后缀数组:将一个字符串的所有后缀按照字典序从小到大进行排序得到的一个数组

给定字符串str,长度为n,位置编号从1到n

Suffix数组(string类型):表示字符串str的后缀

Suffix[i]:字符串str从位置i到位置n(即字符串结尾)构成的一个字符串

后缀i表示Suffix[i];排序是指字符串按照字典序从小到大进行排序

Sa数组(int类型):即所求的后缀数组,也即Suffix数组排序后得到的一个数组(这个数组一般是整数型数组,而不是string类型数组,因为对于一个后缀我们可以用后缀的起始位置pos来表示这个后缀,通过Suffix[pos]就能得到这个后缀)

Sa[i]=x:表示字符串str第i小的后缀是Suffix[x]

Rank数组(int类型):表示后缀字符串排序后是第几

Rank[i]=x:表示后缀i排序后是第x小,也即Sa[x]=i

构造

怎么构造后缀数组呢?暴力的方法是将所有后缀直接进行快速排序,快排的时间复杂度是O(n*logn),因为是对字符串进行排序,排序过程中字符串之间的比较花费的时间不是O(1),而是O(n),所以总的时间复杂度是O(n*n*logn);这样的时间复杂度是我们不能接受的,下面介绍的算法构造后缀数组的时间复杂度只需要O(n*logn)

倍增算法

思想:不断给后缀排序(并不是真正的排序),每次排序后计算后缀的次序号,直到每个后缀的次序号都不同

第一次排序:将每个后缀的前一个字符进行排序

第二次排序:将每个后缀的前两个字符进行排序

第三次排序:将每个后缀的前四个字符进行排序

………………………………………………

第k次排序:将每个后缀的前(2^(k-1))个字符进行排序

要进行多少次排序呢?最多进行logn次排序就能使每个后缀的次序号不同,时间复杂度O(logn)

(重点)怎么计算排序后的次序号?

后缀k的前4个字符是由后缀k的前2个字符和后缀k+2的前两个字符组成,因为每个后缀的前2个字符的次序号已经计算出来了,所以计算任一后缀k的前4个字符的次序号z可以通过比较后缀k的前2个字符的次序号x和后缀k+2的前两个字符的次序号y;将这两个次序号x,y看成一个二元组(x,y),对于计算任一后缀i的前4个字符的次序号zi都有一个二元组(xi,yi),通过二元组的比较就可以得到后缀的前4个字符的次序号。不难发现对于计算后缀前2^n个字符的次序号也适用,只需要从低到高递推即可。

二元组比较规则是:x小则z小;若x相同,y小则z小,若x,y都相同则z相同(很容易理解,因为前面的决定权更大)

图有助于理解:

看到这应该已经差不多理解倍增算法了,但是怎么进行排序呢?

限于篇幅,就将这两种排序方法写在其他博客上了

后缀数组的快速排序实现

后缀数组的基数排序实现

后缀数组(Suffix Array )相关推荐

  1. 看动画学算法系列之:后缀数组suffix array

    文章目录 简介 后缀数组的定义 后缀数组的创建流程 在后缀数组中查找某个字符串 创建LCP 后缀数组和后缀树的比较 简介 在之前的文章中,我们讲到了后缀树和它的一些特性.后缀树主要用来做模式匹配中,比 ...

  2. 算法笔记——后缀数组

    后缀指从某个位置开始到字符串末尾的一个子串,用suffix(i)来表示. 后缀数组(suffix array)指将s的所有后缀从小到大排序后,取其下标i放入数组中,该数组就叫做后缀数组. 表示排名为i ...

  3. 字符串-后缀树和后缀数组详解

    文章目录 后缀树 后缀数组 概念 sa[] rk[] height[] 例题 HDU-1403最长公共子串 洛谷P2408 不同子串个数 HDU-5769Substring 后缀树 建议先了解一下字典 ...

  4. 后缀数组 java实现_后缀数组模板 - java开发指南博客 【转载】 - ITeye博客

    //后缀数组模板 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];//这些都是需要用到的中间变量 int cmp(int *r,int a,int b,int l) { ...

  5. 2020牛客暑期多校训练营(第一场)A B-Suffix Array(后缀数组,思维)

    链接:https://ac.nowcoder.com/acm/contest/5666/A 来源:牛客网 题目描述 The BBB-function B(t1t2-tk)=b1b2-bkB(t_1 t ...

  6. 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)

    题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...

  7. 牛客多校 - B-Suffix Array(后缀数组)

    题目链接:点击查看 题目大意:给出一个只含有 ' a ' 和 ' b ' 的字符串,再给出 B 数组的构造方法如下:对于每个位置 i 来说 如果存在一个位置 j ,使得 j < i 且 s[ j ...

  8. 【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]

    时间限制: 1000ms 内存限制: 65536kB 描述 馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇.在比方说"johnsonj ...

  9. 使用增强型后缀数组(ESA)的文本匹配算法

    设模式串的长度为m,文本的长度为n,使用后缀数组做文本匹配,如果只用后缀表suftab和折半查找算法的复杂度为O(m*logn): 如果使用最长公共前缀表lcptab和折半查找算法,复杂度可以降至O( ...

  10. hdu4416 Good Article Good sentence (后缀数组)

    题意:问a串中有多少种字符串集合B中没有的连续子串. a的长度10^5,B中的总长度为不超过10^5. 解法:后缀数组题目:后缀数组能够非常easy算出来一个串中有多少种子串. 把a和B集合连起来.求 ...

最新文章

  1. 【转】webshell检测——使用auditd进行system调用审计
  2. wordpress-4.4.1 数据库表结构详解
  3. 打用户断点_如何快速测出线缆断点 ?一文了解清楚
  4. Java【全排列 算法 模板】
  5. 最大流之最长递增子序列问题
  6. 鸿蒙系统开发资金,华为终于动手,将拿出超十亿资金,开发者们有福了
  7. mysql复杂查询教程_mysql 复杂查询
  8. ssh远程连接(ubuntu、windows)
  9. Sticky vs fixed
  10. 【GoLang】GO语言系列--002.GO语言基础
  11. linux 进程间广播,Linux系统编程之进程间通信之浅谈信号
  12. Ucinet软件使用
  13. pgAdmin添加外键约束
  14. Postman 安装
  15. android ps模拟器 金手指,电脑ps模拟器金手指的使用教程
  16. 02、单线通讯—SIF通讯协议(一线通)案例一
  17. assimp android build,Windows环境下编译Assimp库生成Android可用的.so文件
  18. zend studio 12.5 安装aptana
  19. SQL Cookbook 系列 - 若干另类目标
  20. Django--学生管理系统(django慢更)

热门文章

  1. 微信小程序 自定义组件之《转盘》
  2. c 语言中析构函数,全面解析C++中的析构函数
  3. 读《我怎样设计飞机》
  4. 21天攻克PET核心词汇,加油!
  5. python判断闰年_python如何判断闰年
  6. 微型计算机的组装步骤,微型计算机系统装配教程
  7. Php实现Facebook app端web网页登陆功能
  8. 最短路径(图论-北京地铁线路查询)
  9. 基于业务流程管理框架的企业敏捷性研究
  10. 计算机软件著作权查询网址