首先说明 :后缀数组的构建在网上有多种方法:朴素的n*n*logn,还有倍增n*logn的,还有3*n的DC3算法,当然还有DC算法。这个算法学习自林厚丛老师的《高级数据结构》,代码较长,而且常数也比较大,但是是我这种笨人可以理解的。如有人想学短而快的可以学习《罗穗骞 后缀数组 ---处理字符串的有力工具》。顺便说一下,罗大神的算法书写的的确很短小也漂亮,可惜我看不懂。

说一下学习的心路历程吧!最开始想学后缀树,道理看明的了,可是一看代码实在是太长了(可能是我找的模版不对吧)。后来看到后缀数组的功能也不错,可以实现后缀树的很多功能,于是转向后缀数组。于是向林大神学习,可是在他漂亮的代码映照下的是我愚笨的脑袋,最后是林厚丛老师救了我。感谢林老师!!!

学习前的准备:

1、后缀数组的各种基本概念

  后缀:字符串中从第i个开始到它的最后一个。如字符串abcde。则bcde、cde、de、e都是他的后缀,当然他本身也是自己的后缀。

  后缀数组:有两种sa数组和rank数组。

    sa[i]表示把字符串的所有后缀排序后排第i的是以第几个字母开头的后缀。

    rank[i]表示以第i个字母开头的后缀在后缀的排序中排第几。

2、计数排序和基数排序(可以百度一下)

  计数排序也就是桶排,时间复杂度O(n)

 1 #include <iostream>
 2 using namespace std;
 3 const int MAXN = 100000;
 4 const int k = 1000; // range
 5 int a[MAXN], c[MAXN], ranked[MAXN];
 6  
 7 int main() {
 8     int n;
 9     cin >> n;
10     for (int i = 0; i < n; ++i) {
11         cin >> a[i]; 
12         ++c[a[i]];
13     }
14     for (int i = 1; i < k; ++i)
15         c[i] += c[i-1];
16     for (int i = n-1; i >= 0; --i)
17         ranked[--c[a[i]]] = a[i];//如果是i表达的是原数标号,a[i]就是排序后的正确序列
18     for (int i = 0; i < n; ++i)
19         cout << ranked[i] << endl;
20     return 0;
21 }
View Code

相关文章: