zoukankan      html  css  js  c++  java
  • [总结] 康托展开及其逆运算

    这里先贴一道例题

    我们先科普一下康托展开

    定义:

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

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

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

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

    康托展开有啥用呢?

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

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

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

    康托展开求法:

    比如 2 1 4 3 这个数,求其展开:

    从头判断,至尾结束,

    ① 比 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 contor(int x[]){
        int p=0;
        for(int i=1;i<=n;i++){
            int t=0;
            for(int j=i+1;j<=n;j++){
                if(x[i]>x[j]) t++;
            }
            p+=t*fac[n-i];
        }
        return p+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  (正解)

    再上代码

    void reverse_contor(int x){
        memset(vis,0,sizeof vis);
        x--;
        int j;
        for(int i=1;i<=n;i++){
            int t=x/fac[n-i];
            for(j=1;j<=n;j++){
                if(!vis[j]){
                    if(!t) break;
                    t--;
                }
            }
            printf("%d ",j);
            vis[j]=1;
            x%=fac[n-i];
        }
        puts("");
    }

    转自

    当你走进这欢乐场
  • 相关阅读:
    更新内容
    小书匠预览操作说明
    小书匠预览操作说明
    2017-4-24(1493037086057未命名文件 测试资源是否正确上传
    ASDASASD
    2017-4-24(1493037086057未命名文件 测试资源是否正确上传
    HttpCanary使用指南——静态注入器
    HttpCanary实战教程
    TC软件分析笔记
    飘零金盾8.5本地笔记
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/8504123.html
Copyright © 2011-2022 走看看