康托和逆康托展开

2024-03-23 06:48
文章标签 展开 康托 逆康托

本文主要是介绍康托和逆康托展开,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.康托展开的解释

康托展开就是一种特殊的哈希函数

  把一个整数X展开成如下形式:

  X=a[n]n!+a[n-1](n-1)!+…+a[2]*2!+a[1]*1!(其中,a为整数,并且0<=a< i,i=1,2,..,n)

  {1,2,3,4,…,n}表示1,2,3,…,n的排列如 {1,2,3} 按从小到大排列一共6个。123 132 213 231 312 321 。

  代表的数字 1 2 3 4 5 6 也就是把10进制数与一个排列对应起来。

  他们间的对应关系可由康托展开来找到。

  如我想知道321是{1,2,3}中第几个大的数可以这样考虑 :

  第一位是3,当第一位的数小于3时,那排列数小于321 如 123、 213 ,小于3的数有1、2 。所以有2*2!个。再看小于第二位2的:小于2的数只有一个就是1 ,所以有1*1!=1 所以小于321的{1,2,3}排列数有2*2!+1*1!=5个
。所以321是第6个大的数。 2*2!+1*1!是康托展开。

  再举个例子:1324是{1,2,3,4}排列数中第几个大的数:第一位是1小于1的数没有,是0个 0*3! 第二位是3小于3的数有1和2,但1已经在第一位了,所以只有一个数2 1*2! 。第三位是2小于2的数是1,但1在第一位,所以
有0个数 0*1! ,所以比1324小的排列有0*3!+1*2!+0*1!=2个,1324是第三个大数。

  康托展开的代码(C语言):

//参数int s[]为待展开之数的各位数字,如需展开2134,则s[4]={2,1,3,4}.
int fac[]={1,1,2,6,24,120,720,5040,40320,362880};//...
long cantor(int s[],int n){int i,j,temp,num;num=0;for(i=1; i < n;i++){//n为位数temp=0;for(int j=i+1;j<=n;j++){if(s[j] < s[i]) temp++;}num+=fac[n-i]*temp;}return (num+1);
}

康托展开的逆运算
  例 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕

  (1)找出第96个数

  首先用96-1得到95

  用95去除4! 得到3余23

  用23去除3! 得到3余5

  用5去除2!得到2余1

  用1去除1!得到1余0有3个数比它小的数是4

  所以第一位是4

  有3个数比它小的数是4但4已经在之前出现过了所以是5(因为4在之前出现过了所以实际比5小的数是3个)

  有2个数比它小的数是3

  有1个数比它小的数是2

  最后一个数只能是1

  所以这个数是45321

  (2)找出第16个数

  首先用16-1得到15

  用15去除4!得到0余15

  用15去除3!得到2余3

  用3去除2!得到1余1

  用1去除1!得到1余0

  有0个数比它小的数是1

  有2个数比它小的数是3 但由于1已经在之前出现过了所以是4(因为1在之前出现过了所以实际比4小的数是2)

  有1个数比它小的数是2 但由于1已经在之前出现过了所以是3(因为1在之前出现过了所以实际比3小的数是1)

  有1个数比它小得数是2 但由于1,3,4已经在之前出现过了所以是5(因为1,3,4在之前出现过了所以实际比5小的数是1)

  最后一个数只能是2

  所以这个数是14352

这篇关于康托和逆康托展开的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/837477

相关文章

通知Notification(可展开的大布局)使用,适配android8.0

补充修正: 2018-11-07 问题:Notification PendingIntent失效,每个通知都响应第一个PendingIntent https://blog.csdn.net/u013370255/article/details/83791750 2018-08-16 问题:app版本更新,通知形式显示安装包下载进度 https://blog.csdn.net/u01337025

vue3 行点击事件 table 树 点击行展开

需求:每次需要点击左侧小按钮才可以展开不方便,提出点击行就展开 el-table 添加 ref="tableDeptRef"@row-click="handleRowClick" 方法 const tableDeptRef = ref()/**行点击事件 */const handleRowClick=(row)=> {tableDeptRef.value.toggleRowExpa

zm-tree-org 数据量过大时,全部展开后,根节点点击收缩,树形消失

zm-tree-org 数据量过大时,全部展开后,根节点点击收缩,树形消失 <zm-tree-orgref="tree"@on-expand="onExpand"</zm-tree-org>export default {methods: {onExpand(e, data) {<!-- 当为根节点,且根节点为闭合时 -->if (data.root === true && data.expa

二叉树展开为列表(LeetCode)

题目 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。 解题 class TreeNode:def __init__(self, val=0, left=None, right=None):self.va

24.9.1(康托展开)

上星期三: 补 24牛客多校 二 C                                                  牛客传送门 思路: 赛时写模拟写的很臭,如果用dp写就很方便 代码如下: const int N=2e6+10;const int mod=1e9+7;ll n;char s[N][2];int dp[N][2];void solve(){c

leetcode 114:二叉树展开为链表

二叉树的题,使用递归的方式 TreeNode *last(TreeNode*root){while(root->right!=NULL){root=root->right;}return root;}TreeNode *fla(TreeNode *root){if(root==NULL)return NULL;if(root->left==NULL&&root->right==NULL)re

求幂级数展开的部分和 / 求分数序列前N项和 / 特殊a串数列求和

习题4-2 求幂级数展开的部分和   (20分) 已知函数e^xe​x​​可以展开为幂级数1+x+x^2 /2! + x^3 /3! + \cdots + x^k /k! + \cdots1+x+x​2​​/2!+x​3​​/3!+⋯+x​k​​/k!+⋯。现给定一个实数xx,要求利用此幂级数部分和求e^xe​x​​的近似值,求和一直继续到最后一项的绝对值小于0.00001。 输入格式:

JQ点击展开二级菜单

JQuery控制点击展开二级菜单,以下为测试代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  <html>      <head>          <title>JQ点击展开二级菜单</title>  <script class="jquery library" src="jquery-

dom练习题-全选反选、可展开子菜单、事件冒泡、二级联动、表格增删、定时器、多事件绑定

checkbox全选反选可展开菜单事件冒泡二级联动菜单表格增删定时器多事件绑定 checkbox全选、反选 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>作业分解小礼包</title><style></style><script>// 全选function checkAll(

android 折叠屏展开收起监听

折叠屏在展开和收起时,屏幕的物理尺寸会发生变化。你可以通过注册一个ComponentCallbacks2的实例来监听屏幕大小的变化。这个接口提供了onConfigurationChanged(Configuration newConfig)方法,当设备的配置发生变化时(包括屏幕大小和方向)会调用此方法。 public class MyActivity extends AppCompatAct