在前面的博文里面分析了SA数组和rank数组的实现过程,实际上也就是倍增算法的思想分析!虽然思想上面懂了,但是代码实现还是很难理解的!因为代码里面做了太多的优化。

整个代码的实现可以分成两部分:1、对所有后缀的第一次排序!运用第一次排序的结果来推算后面的排序!

一、对所有后缀的第一次排序:

  1. for (i = 0; i < m; i++) ws[i] = 0;
  2. for (i = 0; i < n; i++) ws[x[i] = r[i]]++;
  3. for (i = 1; i < m; i++) ws[i] += ws[i - 1];
  4. for (i = n - 1; i >= 0; i--) sa[--ws[x[i]]] = i;

这里用到了x和ws两个辅助数组!一般而言,用一个辅助数组就很难理解了,作者竟然用了两个! 这主要是因为:我们通常用到的排序是value的排序,我们是不理会下标的。而这里是对value排序,但是输出的结果却是下标!所以,这里的排序又变得复杂了。我们不仅要考虑value,还要考虑index,我觉得这才是真正难以理解后缀数组的地方。

这里的排序实际上是用的是,我觉得类似于Hash的方式。把字符串r数组的value映射到辅助数组ws的index。这样的话实际已经排序了,但是我们SA数组存储的是下标,这里才是难点!该怎么做呢?我们知道ws里面存储的其实是r字符串中各个字符的个数。这里我们转化一下,转化成每个字符的排名:比如

假设:ws中是这样存储的:

index:  65 66 67 68 69
value:  1  2  1  1  2

其实就是:字符串中字符及个数分别是:

A:1 B:2 C:1 D:1 E:2

转化成排名:( for (i = 1; i < m; i++) ws[i] += ws[i - 1]; )

则ws变成:

index:  65 66 67 68 69
value:  1  3  4  5  7

这样的话,我们存储下标的时候就可以这样:

for (i = n - 1; i >= 0; i--) sa[--ws[x[i]]] = i;

由于下标从0开始,而且可能相同的字符不止一个,故需要--ws[x[i]]; 就用原字符串逆序的方式把排序后后缀下标存储到sa数组了!

个人感觉计算过程真的是挺精巧的!里面包含的思想,真的值得我深入学习!大牛就是大牛!

由于x数组已经类似于计算出排名了,所以我们不需要真正去计算了,如果需要计算的话:把里面的值减一个最小值然后加1就可以了!

总的来说,只考虑后缀首字母的话,对后缀排序还是比较简单的!更难的在下面用倍增的思想对整个后缀排序的过程。这才是倍增算法的真正核心!上面充其量是预处理罢了!

转载于:https://blog.51cto.com/sbp810050504/1039348

后缀数组的学习(三):SA数组实现代码分析相关推荐

  1. 学习笔记-第一章 恶意代码分析实战

    第一章 从可执行文件提取有用信息的多种方法,包括以下技术:1.使用反病毒软件来确认程序样本的恶意性:2.使用哈希来识别恶意代码:3.从文件的字符串列表,函数和文件头信息中发掘有用信息.字符串包括 AS ...

  2. FreeModbus开源协议栈的移植和详解(三)- RTU协议代码分析

    FreeModbus开源协议栈的移植和详解(三) 目录 概述 一.RTU文件夹的文件 二.mbrtu.c文件 2.1数据类型说明 2.2函数说明 2.1eMBRTUInit()函数 2.2eMBRTU ...

  3. 学习笔记-第九章 恶意代码分析实战

    第九章 OllyDbg 1.加载恶意代码直接加载可执行文件,甚至dll程序.如果恶意代码已经在你的系统上运行,你可以通过附加进程的方式调试它.另外,ollydbg是一个灵活的调试系统,可以使用命令行选 ...

  4. (二)元学习算法MAML简介及代码分析

    欢迎访问个人网络日志

  5. apollo自动驾驶进阶学习之:canbus模块代码分析

    文章目录 封面 代码架构 内容结构 封面 apollo自动驾驶:canbus模块代码讲解及测试(1)引言 apollo自动驾驶:canbus模块代码讲解及测试(2)框架讲解 代码架构 但是apollo ...

  6. 后缀数组(学习心得)

    后缀数组 后缀数组是一种处理字符串的利器,很多字符串的问题都可以通过后缀数组来实现. 后缀数组说简单一点就是对一个字符串的所有后缀子串进行排序. 我来举个例子,比如字符串banana 刚开始的时候它的 ...

  7. 【C 语言】数组 ( 一维数组形参退化 | 二维数组形参退化 | 函数形参等价关系 )

    文章目录 一.一维数组形参退化 二.二维数组形参退化 三.数组形参等价关系 一.一维数组形参退化 C 中将 一维数组 作为参数 , 传递到函数中 , 该 一维数组 会退化为 指针 ; 将 int ar ...

  8. Java中的数组方法and二维数组

    今日份鼓励:如果你想中一颗树,那么它最好的栽种时间,一个是十年前,一个是现在!! 在这里因为博主的知识能力有限,我将会使用自己能够使用并且解释清楚的方法来完成这篇博客 目录 一.数组的拷贝 二.数组的 ...

  9. 后缀数组的学习(一):学习的预备知识

    去年的时候弄了一阵子的后缀数组,当时一直都没有弄懂!今年再看后缀数组,似懂非懂!其实还是没懂!但比去年的完全不懂,还是有进步的! 下来把思路理了理,要看明白后缀数组,是需要一些知识储备的! 1.基数排 ...

最新文章

  1. 蒟蒻吃药计划-治疗系列 #round 2 合并石子+乘积最大
  2. 计算机网络教学重点突破,武汉理工大学计算机网络复习重点教学内容(34页)-原创力文档...
  3. python黑客代码_[翻译]Python开发中的密码散列(Hashing)
  4. 写给大数据开发初学者的话 | 附教程
  5. pymysql(part2)--pymysql使用流程
  6. 实现对顺序表的入栈出栈操作、利用栈将十进制转化成二进制输出【数据结构实验报告】
  7. vmware使用已有linux系统的物理磁盘分区
  8. Java面试通关要点汇总整理
  9. 搭建FileZilla
  10. openstack RC文件的使用
  11. html 页面跳转 加载效果,好看的html页面加载源码带跳转
  12. 1136 mysql_MySQL错误:Error Code: 1136
  13. python和c语言的哪个难,r语言和c语言哪个难 r语言和python的区别-与非网
  14. VScode正则表达式
  15. 值得推荐的在线报表设计器
  16. PPT制作心得与感悟
  17. 20189320《网络攻防》第六周作业
  18. 游戏3D美术设计师前景怎么样?
  19. 历尽千帆,归来仍少年
  20. blogbus博客搬家之图片迁移

热门文章

  1. Linux下yum方式安装mysql 以及卸载mysql
  2. swift菜鸟入门视频教程-03-字符串和字符
  3. 在R中调用Java代码
  4. c语言位段sizeof,C语言位段的介绍
  5. 计算机数控装置论文,数控专业(论文)范文.doc
  6. linux ssh 脚本 密码,ssh自动登录的4种实现方法
  7. wp trackback.php,WordPress工作原理
  8. oracle创建序列seq起始值为1_oracle 重置序列从指定数字开始的方法详解
  9. 鸿蒙系统手机还会出吗,华为最强手机即将到来,可能还有华为鸿蒙系统加入!你期待吗?...
  10. python比前端好学吗_前端学习到底难不难?