关于康托展开

以下定义援引自wiki百科:

康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。

康托展开的公式:

X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!

其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。


例如:

一个排列:3 4 6 5 1 2 7

则计算公式为:2 * 6 ! + 2 * 5 ! + 3 * 4 ! + 2 * 3 ! + 0 * 2 ! + 0 * 1 ! + 0 * 0 !

其中2 * 6 !中的2表示,比3小的数有两个,以这样的数开始的排列有6!个,因此第一项为2*6! 

其中2 * 5 !中的2表示,比4小的数有三个,前面已经有一个3了,故而一共有2个比四小的数可以在第二位出现(如 3 1 .......和 3 2 ......),而以这样的数开始的排列有5!个,因此第一项为2*5!


/*
 *康托展开 
 *Author:Xu.Jin
 *Date:2013/3/25
 *本程序用来计算康托展开的顺序,利用了如下公式公式:
 *                    
 *      X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!
 *
 *Example:
 *
 *请输入n位全排列中的正整数n:7
 *请输入n位全排列:3 4 6 5 1 2 7
 *上述排列在全排列中的顺序是:第1764
 *
 */

package com.xujin;

import java.util.Scanner;

public class Cantor {
	
	public static void main(String...args){
		Cantor cantor = new Cantor();
		while(true){
			cantor.input();
			System.out.println("上述排列在全排列中的顺序是:第" + cantor.claCantor());
		}
	}
	
	//输入
	private void input(){
		System.out.print("请输入n位全排列中的正整数n:");
		number = cin.nextInt();
		System.out.print("请输入n位全排列:");
		permutation = new int[number];
		for(int i = 0; i< number; i++){
			permutation[i] = cin.nextInt();
		}
	}
	
	//计算康托展开
	private int claCantor(){
		int result = 0;
		for(int i = number - 1; i >= 0 ; i--){
			result += fac(i) * modulus(number - 1- i, permutation);
		}
		return result;
	}
	
	//阶乘
	private int fac(int n){
		int res = 1;
		for(int i = n; i >= 1; i--){
			res *= i;
		}
		return res;
	}
	
	//公式前面的系数a[i]
	private int modulus(int index, int[] per){
		int count = per[index] - 1;
		for(int i = 0; i < index; i++){
			if(per[i] < per[index]) count--;
		}
		//System.out.println(count);
		return count;
		
	}
	
	Scanner cin = new Scanner(System.in);
	private int number;
	private int[] permutation;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值