康托展开(Cantor expansion)
康托展开是一个全排列到一个自然数的双射。所以可逆。
康托展开:给定一个数n,和一个n位的全排列,求出这个排列是第几位X
逆康托展开:给定一个数n,和这个排列占第几位X, 求出这个排列
这里X(注意第一个排列是X=0,所以为了方便,我们以后直接+1即可。)
an表示在从(1,2,3,…n)的顺序中,小于an并且没有被排列 的个数。
如34152,
- a5=2(只有1,2小于3)
- a4=2(3被排列了,只有1,2小于4)
- a3=0(没有比1小的)
- a2=1(1,3,4被排列,小于5的只有2)
- a1=0
康拓展开代码实现,复杂度O(N*N)
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int factorial[20]={1,1,2,6,24,120,720,5040,40320,362880,3628800};
int flag[20];
void cantor(int *num,int n){int x=0;int tep=n-1;for(int i=1;i<=n;i++){//遍历num数组 int cot=0;for(int j=1;j<num[i];j++)//找到小于num[i]的数字{if(j<num[i]&&flag[j]==0) cot++; }flag[num[i]]=1;x+=cot*factorial[tep--]; }cout<<x+1;
}
int main(void)
{int num[20]={0,3,4,1,5,2};//求34152在排列中排多少int n=5;cantor(num,n);//n位 }
输出34152是第62个排列
逆康拓展开
前面讨论了X加不加1的问题,如果+1了,这里要-1;如果没有+1,不需要-1
例如 n=5,x=62,排列就是34152,看看如何计算出a5,a4…
- 首先减一:x=61
- a5=x/4!=61/4!=2,说明比首位小的有两个,所以a5=3。x=61%4!=13
- a4=13/3!=2,说明除去首位,比第二小的有2个,所以a4=4。X=13%3!=1
- a3=1/2!=0,说明除去首位和第二位,小于第三位的有0个,所以a3=1。x=1%2!=1
- a4=1/1!=1,所以,a4=5。x=1%1=0
- a5=0/1=0,所以a5=2.最后一个数
即34152.
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int factorial[20]={1,1,2,6,24,120,720,5040,40320,362880,3628800};
int nums[20]={0,1,2,3,4,5,6,7,8,9,10};
vector<int>num(nums+1,nums+11);
void decantor(int n,int x){vector<int>ans;for(int i=n;i>=1;i--){int a=x/factorial[i-1];x=x%factorial[i-1];ans.push_back(num[a]);num.erase(num.begin()+a); }for(auto a:ans) cout<<a;
}
int main(void)
{int n=5;int x=62;decantor(n,x-1);//n位 }
康托展开(Cantor expansion)相关推荐
- 康托展开Cantor expansion 康托逆展开
康托展开 定义 对于n位数的某个排列s[0,n-1],有 X=a[n]∗(n−1)!+a[n−1]∗(n−2)!+...+a[i]∗(i−1)!+...+a[1]∗0! X=a[n]*(n-1)! + ...
- 康托展开和康托展开逆运算(Cantor unfold)
康托展开 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩. 康托展开的实质是计算当前排列在所有由小到大全排列中的名次,因此是可逆的. 公式: X = A[0] * (n-1)! ...
- 【康拓展开逆康托展开】
百度百科就够了 自己的体会: 康托展开是基于比他小的前面的个数来进行计算的 另外康托展开也是一个数组到一个数的映射,因此也是可用于hash,用于空间压缩.比如在保存一个序列,我们可能需要 ...
- HDU 1430 魔板(康托展开+BFS+预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- 康托展开与逆展开(原理+模板)
定义: 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩. 康托展开的实质是计算当前排列在所有由小到大全排列中的名次,因此是可逆的. 原理: 代表在位置i后面且小于的值得个数 (n ...
- 数论--康托展开与逆康托展开模板
ACM常用模板合集 #include<bits/stdc++.h>using namespace std; const int MAX = 13; int Fac[MAX],N; //求出 ...
- 用康托展开实现全排列(STL、itertools)
康拓展开: $X=a_n*(n-1)!+a_{n-1}*(n-2)!+\ldots +a_2*1!+a_1*0!$ X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+ ...
- 基本算法——康托展开与逆康托展开
含义 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩. 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的. 原理 X = s1(n-1)! + s2(n-2 ...
- NOY 139 康托展开
题目链接 NOY 139 我排第几个 现在有"abcdefghijkl"12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小>的? ...
最新文章
- 讲给普通人听的分布式数据存储
- Ogre源码在VS2008(VC9)中的配置方式
- BZOJ 2956 模积和(分块)
- JAVA基础知识(4)
- (转)Python开发规范
- python f.write 保存图片到路径_Python实现生成图片路径和对应标签的方式
- react实现的点击拖拽元素效果
- ubuntu mysql 5.7 远程_ubuntu16.0.4安装mysql5.7以及设置远程访问
- Redis学习总结(21)——Redis持久化是如何做的?RDB和AOF对比分析
- WPF 界面提示加载出错
- Win32中文件的操作
- 来电通java版_还在玩JAVA版《我的世界》?教你怎么转换存档玩光追!
- ubuntu执行configure配置代码出现unable to guess system type报错
- 阿里云前端周刊 - 第 9 期
- 基本SQL语句(一篇就够了)
- 如何在电脑上缓存哔哩哔哩的视频
- c语言为什么要使用short类型,为什么c语言中short的表示范围是-32768~32767?(转)...
- zabbix查询历史数据
- CodeForces - 767C Garland(附带易错数据)
- python开发前景如何
热门文章
- 第十四篇:有概率的上下文无关语法Probabilistic Context-Free Grammar
- 笔试题——max pooling滑动窗口实现(python 代码)
- 基于docker+gunicorn部署sanic项目
- VS2008+QT4.8.7编译QTAV问题和解决方法
- python 的文件目录拷贝转移,自动递归目录建立目录
- 在spring中,prototype scoped bean 如何注入单例bean中
- Linux下利用phpize安装php扩展
- 保险业尚不能完全发挥CRM优势 需强化
- XPath基本概念(一)
- 因特尔显卡自定义分辨率_蓝宝石RX 5600XT 6G D6 白金版OC显卡评测:两千价位段好选择...