zoukankan      html  css  js  c++  java
  • 组合数学——康托展开和逆康托展开

    组合数学——康托展开和逆康托展开

    康托展开运算

                        

        指的是位于位置   i  后面的数小于    值的个数,后面乘的就是后面还有多少个数的阶乘。

    康托展开举例

      5个数的排列组合中,计算  34152  的康托展开值。

    首位是3,则小于 3  的数在后面有有两个为1和2,  ,则首位小于3的所有排列组合为

          
    第二位是4,则小于 4的数在后面有有两个为1和2。因此
          
    第三位是1,则在其之后小于1的数有0个,所以
          
    第四位是5,则在其之后小于5的数有1个,为2,所以
          
    最后一位就不用计算啦,因为在它之后已经没有数了,所以
        
    根据公式:

    所以比 34152  小的组合有61个,即34152是排第62。

    代码实现

    //对前 10 个自然数(0 ~ 9)的阶乘存入表
    const int fact[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
    int cantor(vector<int> vec){//cantor展开,n表示是n位的全排列,a[]表示全排列的数(用数组表示)
        int n= vec.size();
        int ans=0,sum=0;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++)
                if(vec[j]<vec[i])
                    sum++;
            ans+=sum*fact[n-i-1];//累积
            sum=0;//计数器归零
        }
        return ans+1;
    }

    逆康托展开举例

    一开始已经提过了,康托展开是一个全排列到一个自然数的双射,因此是可逆的。即对于上述例子,在
    给出61可以算出起排列组合为34152。由上述的计算过程可以容易的逆推回来,具体过程如下:
    用 61 / 4! = 2余13,说明比首位小的数有2个,所以首位为3。
      
    用 13 / 3! = 2余1,说明在第二位之后小于第二位的数有2个,所以第二位为4。
      
    用 1 / 2! = 0余1,说明在第三位之后没有小于第三位的数,所以第三位为1。
      
    用 1 / 1! = 1余0,说明在第四位之后小于第四位的数有1个,所以第四位为5。
      
    最后一位自然就是剩下的数2。
    通过以上分析,所求排列组合为 34152。

    代码实现

    //对前 10 个自然数(0 ~ 9)的阶乘存入表
    const int fact[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
    vector<int> revContor(int bits, int num) {
        num = num - 1; //有 num - 1 个排列比目标序列要小
        vector<bool> vis(bits + 1, false);
        vector<int> permutation(bits, -1);
        int n, residue = num;
        for (int i = 0; i < bits; ++i) {
            n = residue / (fact[bits - i - 1]);
            residue = residue % (fact[bits - i - 1]);
            for (int j = 1; j <= bits; ++j) {
                if (!vis[j] && !(n--)) {
                    vis[j] = true;
                    permutation[i] = j;
                    break;
                }
            }
        }
        return permutation;
    }

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/14043427.html

  • 相关阅读:
    sqlmap基础使用(以sqli—labs第一关为例)
    IIS、Apache、Nginx日志记录的各个字段内容与含义
    建站+阿里云服务器上传个人制作网页
    SQL server 2005 在Windows server 2003上面的安装
    VMware里kali虚拟机的安装
    第三章web安全基础—http协议及burpsuite基本使用(brupsuite导入证书支持https访问)
    第三章web安全基础—互联网注册网站相关小知识
    第三章web安全基础—IIS发布dvbbs(动网论坛)及SQL2005问题解决
    根据现有目录批量创建文件夹
    PL/SQL通过存储过程为相同数据添加序号
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/14043427.html
Copyright © 2011-2022 走看看