字尾陣列的基數排序實現
阿新 • • 發佈:2018-12-11
基數排序(不懂基數排序的看這裡-->基數排序)
基數排序的時間複雜度是,總的時間複雜度是
C++程式碼實現:
#include <bits/stdc++.h> using namespace std; #define infy 0x3f3f3f3f #define lowbit(x) (x&(-x)) #define e exp(1) #define pi acos(-1) typedef long long int ll; const int maxn=1e6+9; string str; int n; int sa[maxn],c[maxn],tp[maxn],Rank[maxn]; void get_sa(int m) { for(int i=1;i<=m;i++) c[i]=0; for(int i=1;i<=n;i++) c[Rank[i]=str[i]]++; for(int i=2;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[Rank[i]]--]=i; for(int k=1;k<=n;k<<=1) { int p=1; //排序第二關鍵字 for(int i=n-k+1;i<=n;i++) tp[p++]=i; for(int i=1;i<=n;i++) if(sa[i]>k) tp[p++]=sa[i]-k; //排序第一關鍵字 for(int i=1;i<=m;i++) c[i]=0; for(int i=1;i<=n;i++) c[Rank[i]]++; for(int i=2;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[Rank[tp[i]]]--]=tp[i]; tp[sa[1]]=1; p=1; for(int i=2;i<=n;i++) { int fg=1; if(Rank[sa[i]]==Rank[sa[i-1]]) { int xx=sa[i]+k>n?-1:Rank[sa[i]+k]; int yy=sa[i-1]+k>n?-1:Rank[sa[i-1]+k]; if(xx==yy) fg=0; } p+=fg; tp[sa[i]]=p; } swap(Rank,tp); if(p>=n) break; m=p; } } int main() { cin.sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>str; n=str.size(); str=" "+str; get_sa('z'+1); for(int i=1;i<n;i++) cout<<sa[i]<<" "; cout<<sa[n]<<endl; return 0; }