概述
一. 简单介绍:这是一种把每个数都不同的全排列映射为一个自然数的算法,也就是特殊的哈希函数。
康托展开:给定排列,算出在所有全排列中这个排列是第几大。
康托逆展开:给定第几大,求出排列。
二. 康托展开:
首先看有几个数小于最高位,然后这个数乘以数据规模-1的阶乘,累加到一个给定的值里面,然后第二位变为最高位,只向后找小于当前的值,一直到个位。
也就是说213456,找出比2小,有1个2*5!然后依次类推。
三. 康托逆展开:百度百科的例子很好
http://baike.baidu.com/link?url=d9PJo6Qp0C5IR4xIqsxp6JQaAD0aZ8bp-1CQfcYGpWpQu8RUwyp735BEW2yTwUpBYpBB1r23jhbsqF2yxmeMNa
四. 代码:
const int MAX_SIZE = 10;
int fac[MAX_SIZE + 1];
//计算 MAX_SIZE 的阶乘
void getFactorial()
{
int i;
fac[0] = 1;
for(i = 1; i <= MAX_SIZE; i++){
fac[i] = i*fac[i - 1];
}
}
//康托逆展开:
//in为输入的数,ans为得到的排列.
void getArray(int in, int ans[])
{
//k用来保存剩下的数中当前第numOfMin + 1个数是多少。
//numOfMin表示在全部数中有几个数比当前数小。
//showed表示第几个数是否出现过。
int i, j, numOfMin, k;
bool showed[MAX_SIZE + 1] = {0};
in--;
for(i = 0; i < MAX_SIZE; i++){
numOfMin = in / fac[MAX_SIZE - 1 - i];
in = in % fac[MAX_SIZE - 1 - i];
for(j = 0, k = 0; j <= numOfMin; k++)
if(!showed[k])
j++;
k--;
ans[i] = k;
showed[ans[i]] = true;
}
}
//康托展开:
void getNumber(int &ans, int in[])
{
int i, j, numOfMin;
ans = 0;
for(i = 0; i < MAX_SIZE - 1; i++){
numOfMin = 0;
for(j = i + 1; j < MAX_SIZE; j++){
if(in[i] > in[j])
numOfMin++;
}
ans += numOfMin*fac[MAX_SIZE - i - 1];
}
ans++;
}
最后
以上就是爱笑汽车为你收集整理的康托展开与逆展开的全部内容,希望文章能够帮你解决康托展开与逆展开所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复