把题读清楚,题中的输入是包括数字、大写字母和小写字母的。
初始化排名的时候可以把字符的ascii值作为排位,因为排名是可以并列的。但是最后的后缀排名是不可能并列的,因为每一个后缀的长度不一样。
基数排序的时候,注意处理并列的情况。下面的代码是复旦大学的程序设计里面的代码,写的挺清晰的,想看的可以直接粘走。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
struct Node {
int next,now;
}d[maxn];
int pos[maxn],c[maxn],SA[maxn],Rank[maxn],val[maxn][2],n;
char s[maxn];
void add_value(int u,int v,int i)
{
d[i].next=c[u];
c[u]=i;
d[i].now=v;
}
void radix_sort(int l,int r)
{
for (int k=1;k>=0;k--) {
memset(c,0,sizeof(c));
for (int i=r;i>=l;i--) {
add_value(val[pos[i]][k],pos[i],i);
}
int t=0;
for (int i=0;i<maxn;i++) {
for (int j=c[i];j;j=d[j].next) {
pos[++t]=d[j].now;
}
}
}
int t=0;
for (int i=1;i<=n;i++) {
if (val[pos[i]][0]!=val[pos[i-1]][0]||val[pos[i]][1]!=val[pos[i-1]][1]) ++t;
Rank[pos[i]]=t;
}
}
void get_suffix_array()
{
int t=1;
while (t/2<=n) {
for (int i=1;i<=n;i++) {
val[i][0]=Rank[i];
val[i][1]=(i+t/2<=n)?Rank[i+t/2]:0;
pos[i]=i;
}
// for (int i=1;i<=n;i++) {
// printf("val: %d %d
",val[i][0],val[i][1]);
// }
radix_sort(1,n);
t*=2;
// for (int i=1;i<=n;i++) {
// printf("%d ",Rank[i]);
// }
// puts("");
// printf("%d%t",t);
}
for (int i=1;i<=n;i++) {
SA[Rank[i]]=i;
}
}
int main()
{
freopen("in.txt","r",stdin);
scanf("%s",s+1);
n=strlen(s+1);
for (int i=1;i<n+1;i++) {
Rank[i]=(int)s[i];
// printf("%d ",Rank[i]);
}
get_suffix_array();
for (int i=1;i<=n;i++) {
printf("%d",SA[i]);
if (i<n) putchar(' ');
}
return 0;
}