后缀数组学习

快排的代码很容易理解。

1 int sa[MAX],temp[MAX],rank[MAX];
 2 int n,k;
 3 bool cmp_sa(int i,int j) {
 4     if(rank[i]!=rank[j]) return rank[i]<rank[j];
 5     else {
 6         int ri= i+k<=n ? rank[i+k] : -1;
 7         int rj= j+k<=n ? rank[j+k] : -1;
 8         return ri<rj;
 9     }
10 }
11 void construct_sa(string S,int *sa) {
12     n=S.size();
13     for(int i=0;i<=n;i++) {
14         sa[i]=i;
15         rank[i]= i < n ? S[i] : -1;
16     }
17     for(k=1;k<=n;(k<<=1)) {
18         sort(sa,sa+1+n,cmp_sa) ;
19         temp[sa[0]]=0;
20         for(int i=1;i<=n;i++) {
21             temp[sa[i]]=temp[sa[i-1]]+(cmp_sa(sa[i-1],sa[i])? 1 : 0);
22         }
23         for(int i=0;i<=n;i++) {
24             rank[i]=temp[i];
25         }
26     }

27 }

时间: 2024-10-10 23:21:22

后缀数组学习的相关文章

后缀数组学习笔记【详解|图】

后缀数组学习笔记[详解] 老天,一个后缀数组不知道看了多少天,最后终于还是看懂了啊! 最关键的就是一会儿下标表示排名,一会用数值表示排名绕死人了. 我不知道手跑了多少次才明白过来.其实我也建议初学者手跑几遍,但是一定要注意数组的意义,否则就是无用功. 数组含义: s[ ]:输入的字符串,预处理的时候会在末尾加上一个0 sa[ ]:它的下标就是后缀排名 x[ ] = t[ ]:用来保存第一关键字排名,注意!它的数值是排名.初始时恰好是字符串的ASCII码.字典序嘛! y[ ] = t2[ ]:它的

后缀数组学习笔记

现在来看倍增算法是非常好理解的. 直接放一篇blog写的挺好的:http://www.cnblogs.com/zinthos/p/3899725.html 虽然理论复杂度是$O(nlogn)$,但其中各种细节优化确实十分有必要的. 给自己放一个倍增的模板,有空填DC3的坑 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int n,m; 6 cha

学习笔记----后缀数组

学习资料:IOI2009国家集训队论文--<后缀数组> 论文里面写的比较清晰了,但是代码里面没有解释,又从网上找到了一份代码的注释,解释的挺好的 地址:http://www.cnblogs.com/Lyush/p/3233573.html 这里是代码模板: 倍增算法实现的,效率很高. const int maxn = 10010; int wa[maxn], wb[maxn], wv[maxn], ws1[maxn]; int cmp(int *r, int a, int b, int l)

【算法学习】后缀数组

一个字符串的题,有姿势水平的OIers的脑中应该要浮现出许多算法-- 但是我没有姿势,也没有水平,除了KMP和trie树,什么也想不起来. 直到我学了它--后缀数组! 多亏这玩意儿,我现在什么都想不起来了. 后缀数组干嘛用的? 主要处理同一个字符串中的重复子串问题. 如何实现? 注意到每一个子串,都是一个后缀的某个前缀,这个后缀和前缀都是唯一确定的. 而后缀相同的前缀,和他们的字典序有密切联系.你有没有想过,字典中的相邻单词,他们的公共前缀总是很长. 一个字符串的任意后缀,都能用它的起始位置的下

算法学习:后缀数组 height的求取

[定义] [LCP]全名最长公共前缀,两个后缀之间的最长前缀,以下我们定义 lcp ( i , j ) 的意义是后缀 i 和 j 的最长前缀 [z函数] 函数z [ i ] 表示的是,第 i 个后缀和字符串的最长前缀  [解决问题] 这两个算法都是在解决这个问题 即求后缀和字符串和后缀之间的最长公共前缀 但是有所不同的是, 后缀数组最终求出的是,字典序第 i 个后缀和第 i + 1 个后缀的最长公共前缀 z函数最终求出的是,第 i 个后缀和字符串的最长公共前缀 然后通过这个最长公共前缀求一些其他

学习笔记:后缀数组

后缀数组是指对于后缀排序后,每个后缀的位置:sa[rank]=pos:排名为rank的后缀是pos->len这个后缀 note:rank[pos]=rank:位置为pos的串排名为rank 白书上的代码简洁明了,很容易理解. 核心思想:我们对于每个位置开始的后缀,不直接计算,先计算从这个位置开始,向后1位是第几小,然后向后2位,向后4位,一直到*2>n,这时就算好了后缀数组 复杂度:O(n*log(n)^2) :倍增log(n),快排log(n) 代码: bool cp(int x,int y

[后缀数组]【学习笔记】【未完】

研究了好长时间....(诶好像莫比乌斯反演时也说过这句话) 参考资料: 1.http://wenku.baidu.com/link?url=Beh6Asxvtm7M2QY5kiPyKKaP87xvBrNBKW9LXOeGKm-WM4GoUM3opnHZ8z-DahF7TRaLZZ4cpUe6jfFF064XUEmAiIDF7t90CpgNfSC3_Pq 2.http://www.cnblogs.com/staginner/archive/2012/02/02/2335600.html 3.htt

后缀数组的学习

学之前个人觉得还是应该看一下罗穗骞的后缀数组的国家集训队论文,虽然一开始很难看懂(反正我基本上是完全没看懂,现在距离我第一次看那篇文章也过去了1个多月,看了很多别人的论文,现在个人感觉也只是明白了一个大概),但是能理解一个大概 一个数组 s ,长度为len 那么我们总是用suffix(i) 表示从i开始一直到结尾结束,也即i的后缀 因为每个下标的后缀长度绝对不一致,那么每一个后缀都利用字典序排列,所得到的排名 是绝对不会存在一致性的 后缀数组 sa[i] 表示排名第i位的后缀的起始下标 rank

后缀数组 DC3构造法 —— 详解

学习了后缀数组,顺便把DC3算法也看了一下,传说中可以O(n)复杂度求出文本串的height,先比较一下倍增算法和DC3算法好辣. DC3 倍增法 时间复杂度 O(n)(但是常数很大)   O(nlogn)(常数较小) 空间复杂度   O(n)    O(n) 编程复杂度    较高   较低 由于在时间复杂度上DC3的常数比较大,再加上编程复杂度比较高,所以在解决问题的时候并不是最优选择.但是学到了后缀数组还是补充一下的好点. DC3算法的实现: 1:先把文本串的后缀串分成两部分,第一部分是后