X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!。这就是康托展开。康托展开可用代码实现。
把一个整数X展开成如下形式:
X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0!
其中,a为整数,并且0<=a[i]<i(1<=i<=n)
思路:康托展开式的典型应用,康托展开式是什么呢,举个例子。1,2,3这三个数的全排列共有六种,那么按照字典的顺序,『3,2,1』 这个序列是在第几个呢。康托是这样想的:
首先从第一位3开始看,比3小的有2,1,那么也就是说如果第一位是1或者2都在这个序列的前面,那么以1或者2开头的序列有多少呢,答案为2*2!。为什么是这个答案呢?因为符合 要求的第一位共有1和2两个数,然后第二位和第三位组成的排列总数为2!,所以,学过排列组合的都知道,乘起来就可以了(康托展开式本来就是组合数学里面的...)。
康托展开的代码(c语言实现):
//参数 int s[ ]为待展开之数的各位数字,如需展开2134,则s[4]={2,1,3,4};
int fac[ ]={1,1,2,6,24,120,720,...}//储存n!
long cantor(int s[],int n){
int i,j,temp,num=0;
num=o;
for(i=0;i<n;i++){
temp=0;
for(j=i+1;j<n;j++){ //求s[i]后面比它小的数的个数
if(s[j]<s[i]) temp++;
}
num+=temp*fac[n-1-i];
}
return num+1;
}