康托展开公式与全排列应用
时间:2022-07-24
本文章向大家介绍康托展开公式与全排列应用,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
康托展开公式
X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!
怎样知道其中一种排列是有序序列中的第几个?
康托展开. {1...n}的全排列由小到大有序,s[]为第几个数
{1,2,3,4,...,n}的排列总共有n!种,将它们从小到大排序,怎样知道其中一种排列是有序序列中的第几个?
如 {1,2,3} 按从小到大排列一共6个:123 132 213 231 312 321。想知道321是{1,2,3}中第几个大的数。
这样考虑:
- 第一位是3,小于3的数有1、2 。所以有2*2!个。
- 再看小于第二位,小于2的数只有一个就是1 ,所以有1*1!=1
- 所以小于32 的{1,2,3}排列数有22!+11!=5个。所以321是第6个大的数。
22!+11!是康托展开。
康托逆运算
康托展开的逆运算. {1...n}的全排列,中的第k个数为s[] {1,2,3,4,5}的全排列已经从小到大排序,要找出第16个数:
1. 首先用16-1得到15
2. 用15去除4! 得到0余15
3. 用15去除3! 得到2余3
4. 用3去除2! 得到1余1
5. 用1去除1! 得到1余0
6. 有0个数比它小的数是1所以第一位是1
7. 有2个数比它小的数是3,但1已经在之前出现过了所以是4
8.有1个数比它小的数是2,但1已经在之前出现过了所以是3
9.有1个数比它小的数是2,但1,3,4都出现过了所以是5
最后一个数只能是2
所以这个数是14352
代码
public class KangTuo {
/**
* 康托展开:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!
* ai为整数,并且0<=ai<i(1<=i<=n)
*/
private int fac[] = {1,1,2,6,24,120,720,5040,40320}; //i的阶乘为fac[i]
/*
* 康托展开. {1...n}的全排列由小到大有序,s[]为第几个数
* {1,2,3,4,...,n}的排列总共有n!种,将它们从小到大排序,怎样知道其中一种排列是有序序列中的第几个?
*
* 如 {1,2,3} 按从小到大排列一共6个:123 132 213 231 312 321。想知道321是{1,2,3}中第几个大的数。
* 这样考虑:第一位是3,小于3的数有1、2 。所以有2*2!个。再看小于第二位,小于2的数只有一个就是1 ,所以有1*1!=1 所以小于32
*
* 的{1,2,3}排列数有2*2!+1*1!=5个。所以321是第6个大的数。2*2!+1*1!是康托展开。
*/
public int KangTuo(int n, int s[])
{
int sum = 0;
for(int i = 0; i < n; i++){
int t = 0;
for(int j = i+1; j < n;j++){
if(s[i] > s[j]){
t++;
}
}
sum += t *fac[n-i-1];
}
return sum+1;
}
/*
* 康托展开的逆运算. {1...n}的全排列,中的第k个数为s[] {1,2,3,4,5}的全排列已经从小到大排序,要找出第16个数:
*
* 1. 首先用16-1得到15
*
* 2. 用15去除4! 得到0余15
*
* 3. 用15去除3! 得到2余3
*
* 4. 用3去除2! 得到1余1
*
* 5. 用1去除1! 得到1余0
*
* 有0个数比它小的数是1
*
* 所以第一位是1
*
* 有2个数比它小的数是3,但1已经在之前出现过了所以是4
*
* 有1个数比它小的数是2,但1已经在之前出现过了所以是3
*
* 有1个数比它小的数是2,但1,3,4都出现过了所以是5
*
* 最后一个数只能是2
*
* 所以这个数是14352
*/
public void invKT(int n, int k, int s[]) {
int i, j, t;
int[] vst = new int[8];
k--;
for (i = 0; i < n; i++) {
t = k / fac[n - i - 1];
for (j = 1; j <= n; j++)
if (0 == vst[j]) {
if (t == 0)
break;
t--;
}
s[i] = j;
vst[j] = 1;
k %= fac[n - i - 1];
}
}
/**
* @param args
*/
public static void main(String[] args) {
// int[] s = new int[]{1,2,4};
int[] s = new int[]{3,2,1};
System.out.println(new KangTuo().KangTuo(s.length, s));
}
}
- Highway Networks
- CTF---编程入门第一题 循环
- Z.ExtensionMethods 一个强大的开源扩展库
- 【干货】神经网络SRU
- AutoMapper 使用实践
- CTF---安全杂项入门第二题 A记录
- PyTorch(总)---PyTorch遇到令人迷人的BUG与记录
- 手把手带你进入TOP20的商超销售预测
- 【干货荟萃】机器学习&深度学习知识资料大全集(二)(论文/教程/代码/书籍/数据/课程等)
- 逆天通用水印扩展篇~新增剪贴板系列的功能和手动配置,卸除原基础不常用的功能
- 【专知-Java Deeplearning4j深度学习教程06】用卷积神经网络CNN进行图像分类
- 万恶的剪贴板==》为存储而生
- AdaBoost算法(R语言)
- CTF---Web入门第六题 因缺思汀的绕过
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法