Reprinted from: http://blog.csdn.net/lttree/article/details/24798653 slightly trimmed
Cantor launched what is?
definition:
X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!
ai is an integer and 0 <= ai <i (1 <= i <= n)
Simple point that is, determine the number of small to large have a place in the whole arrangement of their respective numbers.
132 For example, the first two rows in the full array 1,2,3.
Cantor Expand dim it?
Definition: the n-bit (0 ~ n-1) the whole arrangement, which is unique and a maximum of about Cantor expand n !, thus may be stored by these arrangements a smaller space. Inverse by the formula X may be arranged corresponding to the whole launch.
It can be applied to the hash table space compression,
And when searching for certain types of questions, the VIS array Compression. For example: eight puzzle , Rubik's Magic . .
Cantor Expand Seeking:
For example, the number 2143, seeking to expand them:
Analyzing the head to the tail end,
① ratio (first digit) small number of how many 2 -> 1It is 1,1 * 3!
② (second digit) there is a smaller number than the number 1 -> 00*2!
③ There are smaller than the number (the third digit) number of 4 -> 3That is, 1,2,3, 1,2 but there have been before, so 1 * 1!
All the products are summed = 7
Seven smaller than the count, so that the position of the rows 8.
1234 1243 1324 1342 1423 1432
2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421
4123 4132 4213 4231 4312 4321
To achieve is to use the program:
int fac[]= {1,1,2,6,24,120,720,5040,40320}; //i的阶乘为fac[i]
// 康托展开-> 表示数字a是 a的全排列中从小到大排,排第几
// n表示1~n个数 a数组表示数字。
int kangtuo(int n,char a[])
{
int i,j,t,sum;
sum=0;
for(i=0; i<n ; ++i)
{
t=0;
for(j=i+1; j<n; ++j)
if(a[i]>a[j])
++t;
sum+=t*fac[n-i-1];
}
return sum+1;
}
Cantor expanded the inverse operation:
Cantor is expanded to a full permutation bijective natural, it can be used as a hash function.
Of course, it can also be the inverse operation.
Inverse calculation method:
Hypothesis 4-digit number in the 19th position.
① 19 minus 1 → 18
② 18 of three! We have made a division → 03
③ 0 pair 2! We have made a division → 00
④ 0-to-1! We have made a division → 00
According to the above it can be seen:
We first digit (leftmost number), there is smaller than the first three-digit number, the first digit is obviously → 4
It is smaller than the second number of digits has 0, the second median → 1
Is smaller than the third number of digits has 0, 1 has been used since, the third median → 2
The fourth remaining three digits
The number is 4123 (n Solutions)
Codes to achieve the above with the steps of:
int fac[]= {1,1,2,6,24,120,720,5040,40320};
//康托展开的逆运算,{1...n}的全排列,中的第k个数为s[]
void reverse_kangtuo(int n,int k,char s[])
{
int i,j,t,vst[8]= {0};
--k;
for(i=0; i<n; i++)
{
t=k/fac[n-i-1];
for(j=1; j<=n; j++)
if(!vst[j])
{
if(t==0)
break;
--t;
}
s[i]='0'+j;
vst[j]=1;
k%=fac[n-i-1];
}
}