康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。康托展开的实质是计算当前排列在所有由小到大全排列的顺序,因此是可逆的。
原理介绍:
公式:
其中,为整数,并且,.
表示原数的第i位在当前未出现的元素中是排在第几个
举个例子:
在5个数的排列组合中,计算 34152的康托展开值。
首位是3,则小于3的数有两个,为1和2,没有出现过的元素,所以,则首位小于3的所有排列组合为
第二位是4,由于第一位小于4,小于4的数有1、2、3,当前没有出现过的元素只剩2个,所以其实计算的是在第二位之后小于4的个数。因此。
第三位是1,则在其之后小于1的数有0个,所以。
第四位是5,则在其之后小于5的数有1个,所以。
最后一位就不用计算啦,因为在它之后已经没有数了,所以
根据公式:
所以比34152小的组合有61个,即34152是排第62。
代码实现:
package 模板; public class 康托展开代码实现 { public static void main(String[] args) { // TODO Auto-generated method stub int[] a= {2,1,4,3}; System.out.println(Cantor(a)); } public static int Cantor(int[] a) { //计算该状态下的康托展开 int res=0; int[] fac= {1,1,2,6,24,120,720,5040,40320}; //0到9各个数的阶乘 for(int i=0;i<a.length;i++) { int temp=0; //比a[i]小的数的个数 for(int j=i+1;j<a.length;j++) { if(a[i]>a[j]) temp++; //在i之前出现过比a[i]小的数要去掉 } res+=temp*fac[a.length-i-1]; } return res+1; } }
09-16
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交