Suffix Array 后缀数组
后缀数组
顾名思义。SuffixArray(下面有时简称SA) 和字符串的后缀有关。
后缀:字符串中某个位置一直到结尾的子串。(SA中讨论包含了原串和空串)。所以共同拥有len+1个后缀。
后缀数组: 字符串的全部后缀组成的按字典序从小到大排好的数组。因为SA中记录的都是字符串的后缀,所以SA仅仅须要记录其表示的后缀的起始位置。
因为比較字典序是O(n)的,所以暴力算法的复杂度将是O(n^2logn)。通过一些算法能够降到线性复杂度。这里先介绍一种简单的O(nlognlogn)的算法。
该算法的思想是通过倍增法减少了比較字典序的大小的复杂度O(n)到O(logn)。
其求解时不先算后缀,而是先算长度为1的子串的字典序大小排列,然后得到一个rank数组,即该子串在全部子串中排位的值。字典序越小,rank值越小。
rank[k][i] 表示起始位置为i的长度为k的子串在全部长度为k的子串中的字典序大小。
这时我们要比較长度为2k的子串的大小的话。其第i个位置的长度为2k的子串的大小能够通过比較rank[k][i]和rank[k][i+k]来实现。
SA中的sa[i]表示字典序位i的后缀串的起始位置。
const int MAXN = 100000 + 5;
int _k, _len;
int _rank[MAXN];
int _tmp[MAXN];
int _sa[MAXN];// 后缀数组。 bool _cmp(int i, int j) {
if (_rank[i] == _rank[j]) {
int _ri = (i+_k <= _len) ? _rank[i+_k] : -1;
int _rj = (j+_k <= _len) ? _rank[j+_k] : -1;
return _ri < _rj;
} else {
return _rank[i] < _rank[j];
}
} void Suffix_sa(string s, int* sa) {
_len = s.size(); for (int i=0; i<_len; i++) {
sa[i] = i;
_rank[i] = s[i];
}
sa[_len] = _len;
_rank[_len] = -1; for ( _k=1; _k<=_len; _k<<=1) {
sort(sa, sa+_len+1, _cmp); _tmp[sa[0]] = 0; for (int i=1; i<=_len; i++) {
_tmp[sa[i]] = _tmp[sa[i-1]];
if (_cmp(sa[i-1], sa[i])) {
_tmp[sa[i]]++;
}
} copy(_tmp, _tmp+_len+1, _rank);
}
}
Suffix Array 后缀数组的更多相关文章
- suffix array后缀数组
倍增算法 基本定义子串:字符串 S 的子串 r[i..j],i≤j,表示 r 串中从 i 到 j 这一段也就是顺次排列 r[i],r[i+1],...,r[j]形成的字符串. 后缀:后缀是指从某个位置 ...
- bzoj 4319: Suffix reconstruction 后缀数组+构造
题目大意 给定后缀数组sa,要求构造出满足sa数组的字符串.或输出无解\(n\leq 5*10^5\) 题解 我们按照字典序来考虑每个后缀 对于\(Suffix(sa[i])\)和\(Suffix(s ...
- BZOJ 4319: cerc2008 Suffix reconstruction(后缀数组)
题面 Description 话说练习后缀数组时,小C 刷遍 poj 后缀数组题, 各类字符串题闻之丧胆.就在准备对敌方武将发出连环杀时,对方一记无中生有,又一招顺 手牵羊,小C 程序中的原字符数组就 ...
- BZOJ.4319.[cerc2008]Suffix reconstruction(后缀数组 构造 贪心)
题目链接 \(Description\) 给定SA数组,求满足SA[]的一个原字符串(每个字符为小写字母),无解输出-1. \(Solution\) 假设我们现在有suf(SA[j]),要构造suf( ...
- 后缀数组(suffix array)
参考: Suffix array - Wiki 后缀数组(suffix array)详解 6.3 Suffix Arrays - 算法红宝书 Suffix Array 后缀数组 基本概念 应用:字 ...
- 后缀数组(suffix array)详解
写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...
- 利用后缀数组(suffix array)求最长公共子串(longest common substring)
摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其 ...
- 笔试算法题(40):后缀数组 & 后缀树(Suffix Array & Suffix Tree)
议题:后缀数组(Suffix Array) 分析: 后缀树和后缀数组都是处理字符串的有效工具,前者较为常见,但后者更容易编程实现,空间耗用更少:后缀数组可用于解决最长公共子串问题,多模式匹配问题,最长 ...
- 数据结构之后缀数组suffix array
在字符串处理当中,后缀树和后缀数组都是非常有力的工具,其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料.其实后缀是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多 ...
随机推荐
- CSS Flexbox 弹性盒子模型
CSS Flexbox 弹性盒子模型 设置元素样式为 display: flex 或 display: inline-flex, 让元素变成flex容器, 从而可以通过flex模式布局它的子元素. f ...
- js判读周末以及节假日
两个链接,搞定! http://bbs.csdn.net/topics/10417668 http://www.jb51.net/article/131660.htm
- linux下恢复被删除的文件
https://cloud.tencent.com/developer/article/1028317
- cropper+pillow处理上传图片剪裁(二)
上次说到处理上传头像的方法是临时保存在本地,其实这样做并不妥,而且修改后的头像重新上传到model中也很麻烦,差了很多资料,解决了这个问题 大致思路:用户上传原图和修改数据—PIL修改后将图片保存为内 ...
- [Offer收割]编程练习赛35
有歧义的号码 #include<stdio.h> #include<string.h> #include<stdlib.h> int cmp(const void ...
- 第五课: - Stack / Unstack / Transpose函数
第 5 课 我们将简要介绍 stack 和 unstack 以及 T (Transpose)函数. 在用pandas进行数据重排时,经常用到stack和unstack两个函数.stack的意思是堆 ...
- Activity创建时布局文件的实现原理
setContenView(R.id.activity)实现原理 1.底层框架根据布局ID找到布局文件. 2.底层框架解析此布局文件(pull解析). 3.底层框架通过反射构建布局文件中的元素对象(E ...
- 验证码识别 Tesseract的简单使用和总结
Tesseract是什么 OCR即光学字符识别,是指通过电子设备扫描纸上的打印的字符,然后翻译成计算机文字的过程.也就是说通过输入图片,经过识别引擎,去识别图片上的文字.Tesseract是一种适用于 ...
- 文件系统VFS数据结构(超级块 inode dentry file)(收集整理)
Linux虚拟文件系统四大对象: 1)超级块(super block) 2)索引节点(inode) 3)目录项(dentry) 4)文件对象(file) 一个进程在对一个文件进行操作时各种对象的引用过 ...
- 如何选择优动漫PAINT版本?是个人版还是EX版
优动漫PAINT也就是我们常说的clip studio paint(CSP)的中文版本,它是一款功能强大的动漫绘图软件,适用于个人和专业团队创作,分为个人版和EX版.搭载了绘制漫画和插画所需的所有功能 ...