一. 简单介绍:这是一种把每个数都不同的全排列映射为一个自然数的算法,也就是特殊的哈希函数。
康托展开:给定排列,算出在所有全排列中这个排列是第几大。
康托逆展开:给定第几大,求出排列。
二. 康托展开:
首先看有几个数小于最高位,然后这个数乘以数据规模-1的阶乘,累加到一个给定的值里面,然后第二位变为最高位,只向后找小于当前的值,一直到个位。
也就是说213456,找出比2小,有1个2*5!然后依次类推。
三. 康托逆展开:百度百科的例子很好
http://baike.baidu.com/link?url=d9PJo6Qp0C5IR4xIqsxp6JQaAD0aZ8bp-1CQfcYGpWpQu8RUwyp735BEW2yTwUpBYpBB1r23jhbsqF2yxmeMNa
四. 代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47const 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++; }
最后
以上就是爱笑汽车最近收集整理的关于康托展开与逆展开的全部内容,更多相关康托展开与逆展开内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复