康拓展开—理解

1公式编辑

把一个整数X展开成如下形式:
X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0! [1]  
其中,a为整数,并且0<=a[i]<i(1<=i<=n)
理解: 对一组数进行全排列后,可以得出它在其中的位置数(由小到大), 另外也是最重要的,可以实现对数据的压缩!



public class Main7
{
	public static final int[]fac = {1,1,2,6,24,120,720,5040,40320,362880};
	
    public static void main(String[] args)
	{
    	String str = "12345";
    	
	   // 建立Hash表  , 得出num在 str这三个数字全排列中是第几个
    	String num1 = "12453";
    	System.out.println(getHash(num1, str));
    	
       // 逆Hash表 , 给出一个数字,得出他的顺序
        int num2 = 16;
        System.out.println(reverHash(num2, str));
	}

	private static String reverHash(int num, String str)
	{
	    num--;	
	    boolean step[] = new boolean[str.length()];
	    StringBuffer sb = new StringBuffer();
	    int j,k;
	    for (int i = 0; i < str.length(); i++)
	    {
	    	int t = num / fac[str.length()-i-1];
	    	num -= t * fac[str.length()-i-1];
	    	for (j = 0, k = 0; k <= t; j++)
	    	    if (!step[j]) k++;	
	    	step[j-1] = true;
	    	sb.append(str.charAt(j-1));
	    }
	    return sb.toString();
	}

	private static int getHash(String num, String str)
	{
        int sum = 0;
		for (int i = 0; i < num.length(); i++)
		{
			int temp = 0;
			for (int j = i + 1; j < num.length(); j++)
              if (num.charAt(i) > num.charAt(j)) temp++;
			sum += temp * fac[str.length()-i-1];
		}
		return sum+1;
	}
}

具体详情: 参考 康托展开 百度百科。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值