后缀数组 救命版

大家都知道后缀数组很cao dan,需要给予基数排序(时间复杂度:N*LogN)

下面带来N*Log2 N 的做法(然而并慢不了多少)

代码 30行,不要基数排序  

 1 int n,k,rank[MAX_N+1],tmp[MAX_N+1];
 2 //比较rank[i],rank[i+k]和rank[j],rank[j+k]
 3 bool compare_sa{
 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 // 正题 计算字符串S的后缀数组
12 void con_sa(strint s,int *sa){
13     n=s.length();
14     // 初始长度为1 rank直接取字符编码
15     for(int i=0;i<=n;i++){
16         sa[i]=i;
17         rank[i]= i<n ? s[i] : -1;
18     }
19     // 利用长度为K的排序的结果对长度为2K的进行排序
20     for(int k=1;k<=n;k *= 2){
21         sort(sa,sa+n+1,compare_sa);
22         tmp[sa[0]]=0;
23         for(int i=1;i<=n;i++){
24             tmp[sa[i]]=tmp[sa[i-1]] + 
25                 (compare_sa(sa[i-1],sa[i]) ? 1 : 0);
26         }
27         for(int i=0;i<=n;i++)
28             rank[i]=tmp[i];
29     }
30 }

 

posted @ 2017-02-21 21:47  浮华的终成空  阅读(132)  评论(0编辑  收藏  举报

Contact with me