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
在字符串处理当中,后缀树和后缀数组都是非常有力的工具,其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料.其实后缀是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多 ...
随机推荐
- Vue2.0框架搭建基础操作及目录说明
一.概述 vue.js是一套构建用户界面的渐进式框架.vue采用自底向上增量开发的设计.vue的核心库只关心视图层,非常容易学习,非常容易与其它库和已有项目整合.vue完全有能力驱动采用单文件组件和v ...
- SqlServer显示“正在还原...”
还原数据库时,提示还原成功,但是数据库一直显示“正在还原...”的状态. 可以通过执行以下命令即可 RESTORE DATABASE DB_NAME WITH RECOVERY 原因: 关于recov ...
- 无序列表属性 隐藏方式 JS简介
今天考试了,整理一下错题. 1.无序列表的属性 list-style 分为三小类 (1)list-style-type none:无标记. disc:实心圆(默认). circle:空心圆. squa ...
- 第三课 创建函数 - 从EXCEL读取 - 导出到EXCEL - 异常值 - Lambda函数 - 切片和骰子数据
第 3 课 获取数据 - 我们的数据集将包含一个Excel文件,其中包含每天的客户数量.我们将学习如何对 excel 文件进行处理.准备数据 - 数据是有重复日期的不规则时间序列.我们将挑战数 ...
- (转)一个vue路由参数传递的注意点
首先我的路由的定义 { path: '/b', name: 'B', component: resolve => require(['../pages/B.vue'], resolve) } 我 ...
- javascript中异常处理案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SQL Server-语句类别、数据库范式、系统数据库组成
前言 终于等到这一天,我要开始重新系统学习数据库了,关于数据库这块,不出意外的话,每天会定时更新一篇且内容不会包含太多,简短的内容,深入的理解,Always to review the basic ...
- 【Python3】POP3协议收邮件
初学Python3,做一个email的例子,虽然知道做的很渣渣,还是分享一下吧 POP3协议 POP3全称Post Official Protocol3,即邮局协议的第三个版本,它规定了怎样将个人计算 ...
- python指定日期后加几天判断
#!/usr/bin/python import datetime import sys arg1_list=list(sys.argv[1].split(',')) arg2_list=list(s ...
- sublime Text3的使用
sublime text百度百科: Sublime Text 是一个代码编辑器,也是HTML和散文先进的文本编辑器.Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python ...