康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的名次,因此是可逆的。
这个算出来的数康拖展开值,是在所有排列次序 - 1的值,因此X+1即为在全排列中的次序:
1 int cantor(int a[5]){ 2 int k,ans=0; 3 for(int i=0;i<4;i++){ 4 k=0; 5 for(int j=i+1;j<5;j++) 6 if(a[j]<a[i]) k++; 7 8 ans+=FAC[4-i]*k; 9 } 10 return ans; 11 }
同理,我们可以用一个数组标记已经用过的数,逆推出数列:
void decantor(int m){ bool flag[6]={}; int k,pos; for(int i=4;i>=0;i--){ pos=4-i; k=m/FAC[i]+1; //寻找位置 for(int j=1;j<=5;j++){ if(flag[j]==0) k--; if(!k){ b[pos]=j; flag[j]=1; break; } } m%=FAC[i]; } }