前文:

这个东东是我准备进攻一道A*算法的八数码题目时,遇到的。

决定先搞懂这个,再进攻八数码(传说中  不做人生不完整的 题目)。

康托展开是什么?

定义:

X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!

ai为整数,并且0<=ai<i(1<=i<=n)

简单点说就是,判断这个数在其各个数字全排列中从小到大排第几位。

比如 132,在1、2、3的全排列中排第2位。

康托展开有啥用呢?

维基:n位(0~n-1)全排列后,其康托展开唯一且最大约为n!,因此可以由更小的空间来储存这些排列。由公式可将X逆推出对应的全排列。

它可以应用于哈希表中空间压缩,

而且在搜索某些类型题时,将VIS数组量压缩。比如:八数码、魔板。。

康托展开求法:

比如2143 这个数,求其展开:

从头判断,至尾结束,

① 比 2(第一位数)小的数有多少个->1个就是1,1*3!

② 比 1(第二位数)小的数有多少个->0个0*2!

③ 比 4(第三位数)小的数有多少个->3个就是1,2,3,但是1,2之前已经出现,所以是  1*1!

将所有乘积相加=7

比该数小的数有7个,所以该数排第8的位置。

1234  1243  1324  1342  1423  1432
2134  2143  2314  2341  2413  2431
3124  3142  3214  3241  3412  3421
4123  4132  4213  4231  4312  4321

用程序来实现就是:

int  fac[] = {1,1,2,6,24,120,720,5040,40320}; //i的阶乘为fac[i]
// 康托展开-> 表示数字a是 a的全排列中从小到大排,排第几
// n表示1~n个数  a数组表示数字。
int kangtuo(int n,char a[])
{int i,j,t,sum;sum=0;for( i=0; i<n ;++i){t=0;for(j=i+1;j<n;++j)if( a[i]>a[j] )++t;sum+=t*fac[n-i-1];}return sum+1;
}

康托展开的逆:

康托展开是一个全排列到自然数的双射,可以作为哈希函数。

所以当然也可以求逆运算了。

逆运算的方法:

假设求4位数中第19个位置的数字。

① 19减去1  → 18

② 18 对3!作除法 → 得3余0

③  0对2!作除法 → 得0余0

④  0对1!作除法 → 得0余0

据上面的可知:

我们第一位数(最左面的数),比第一位数小的数有3个,显然 第一位数为→ 4

比第二位数小的数字有0个,所以 第二位数为→1

比第三位数小的数字有0个,因为1已经用过,所以第三位数为→2

第四位数剩下 3

该数字为  4123  (正解)

用代码实现上述步骤为:

int  fac[] = {1,1,2,6,24,120,720,5040,40320};
//康托展开的逆运算,{1...n}的全排列,中的第k个数为s[]
void reverse_kangtuo(int n,int k,char s[])
{int i, j, t, vst[8]={0};--k;for (i=0; i<n; i++){t = k/fac[n-i-1];for (j=1; j<=n; j++)if (!vst[j]){if (t == 0) break;--t;}s[i] = '0'+j;vst[j] = 1;k %= fac[n-i-1];}
}

康托展开及其逆运算 详解相关推荐

  1. [总结] 康托展开及其逆运算

    这里先贴一道例题 我们先科普一下康托展开 定义: X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! ai为整数,并且0<=ai<i ...

  2. 关于数论【康托展开及其逆运算】

    表示这个东西背了很多次,但是次次忘,希望这次能够记住吧. 康托展开: 问45231是n=5的全排列中第几个排列? ans:= 3*4! + 3*3! + 1*2! + 1*1! + 0*0! =93 ...

  3. 是否显示展开_Creo7.0教程之绝对精度对钣金件展开的作用详解

    在讲Creo7.0绝对精度对钣金展开的帮助之前,我们有必要先来说明一下Creo的精度定义. 刚使用Creo7.0版本的新建模型,很多网友就问,怎么模板文件中有两个同样单位的选择,"abs&q ...

  4. 康托展开式---我排第几+逆康托展开

    之前一直不想看这个康托展开定理因为真的很不理解,但是现在还是勇敢的面对了~  {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个.123 132 ...

  5. 关于康托展开的用途及写法

    在处理八数码这一类需要用到全排列的问题的时候, 存储往往是一个难题, 因为明明只有n!种情况, 数字的长度却有n, 用数组是肯定不行的. 这个时候, 康托展开就派上了用场, 当然, 在条件允许的情况下 ...

  6. 康托展开(基于全排列的某一种hash)

    康托展开: X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! ai为整数,并且0<=ai<i(1<=i<=n) 先举个 ...

  7. 什么是TCP三次握手和四次挥手【重点学习系列---干货十足--一文详解】

    引言 本文将会从一个爱情的故事开始,着力从什么是三次握手.为什么是三次而不是俩次或者四次.TCP关闭的过程.为什么要四次挥手.而不是三次.为什么最后是2MSL.什么是2MSL这些问题展开分析,详解,让 ...

  8. 康托展开详解 -csdn博客

    康托展开详解 -csdn博客 定义: 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩. 康托展开的实质是计算当前排列在所有由小到大全排列中的名次,因此是可逆的. 原理介绍 **X ...

  9. 详解康托展开与逆康托展开

    康托展开 rank=an(n−1)!+an−1(n−2)!+⋯+a10! 再举个例子说明. 在(1,2,3,4,5)5个数的排列组合中,计算 34152的康托展开值. 首位是3,则小于3的数有两个,为 ...

最新文章

  1. 数据结构(七)图的遍历(递归非递归方法)
  2. win10中linux系统下载软件,win10 上安装 Debian Linux子系统
  3. 深度学习笔记(18) 迁移学习
  4. C++之操作符重载探究(七):==运算符重载
  5. paip.提升安全性-------用户口令密码的检测与生成
  6. 如何使用命令行进行基本操作
  7. 总结——pandas/numpy处理数据中文手册速查
  8. zooInspector下载
  9. python批量修改图片格式、重命名
  10. 2021高考北京大峪中学成绩查询,2014年北京市各区高考成绩汇总
  11. flappy bird用java实现_java实现Flappy Bird游戏源代码
  12. 3D动画制作太复杂?谷歌推出MonsterMash,绘画小白都能用
  13. 从外包测试到阿里巴巴,一位三本女生逆袭之路
  14. wwwxxx域名选择(www.xxx.com或者.cn)
  15. 对策论基础---矩阵对策的解法
  16. 【最新】CUDA Toolkit版本及可用PyTorch对应关系(参考官网)
  17. 机器学习必备算法之(一)逻辑回归(logistics regression)及Python实现
  18. 使用RMAN实现异机备份恢复(WIN平台)
  19. 不用 is 做变量名前缀 生成代码会漏掉 is字符串
  20. 丹麦奥尔堡大学计算机系博士,关于选拔博士研究生攻读上海大学-丹麦奥尔堡大学双博士学位的通知...

热门文章

  1. C++ Virtual详解
  2. 小程序 报错 errcode: 40029, errmsg: invalid code, hints: [ req_id: HQd79a0747th31 ]
  3. 简单工厂,工厂,抽象工厂
  4. 最大可传输单元 MTU 对 UDP/TCP 包的大小限制
  5. 搭建属于自己的发卡小店-独角数卡
  6. 分享一款电机控制国产32位单片机MM32SPIN360C
  7. c语言堆、栈、数据段、代码段、bss段的疑惑
  8. #莫队,分块#codevs 6555 洛谷 1494 jzoj 1902 小Z的袜子
  9. 查找二叉树(BST)
  10. 高通量测序与生物信息学面临的挑战