zoukankan      html  css  js  c++  java
  • 康托展开与逆康托展开

    简述:康托展开是一个全排列到一个自然数的双射,常用于构建hash表时的空间压缩。设有n个数(1,2,3,4,…,n),可以有组成不同(n!种)的排列组合,

       康托展开表示的就是是当前排列组合在n个不同元素的全排列中的名次。

    康拓展开

    X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! ,其中a[i]为当前未出现的元素中是排在第几个(从0开始)

    举例:在(1,2,3,4,5)5个数的排列组合中,计算 34152的康托展开值为61

    代码:

    #include<iostream> 
    #include<cstdio>
    #include<cstring>
    using namespace std;
    long int factory[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
    long contor(char str[], int n) {
        long result = 0;
        for(int i = 0; i < n; i++) {
            long count = 0; 
            for(int j = i+1; j < n; j++) {
                if(str[j] < str[i]) count++; 
            }
            result += count*factory[n-i-1]; 
        } 
        return result; 
    }
    int main() {
        char str[100];
        cin >> str;
        cout << contor(str, strlen(str));
        return 0;
    } 

    逆康托展开

    在(1,2,3,4,5)给出61可以算出起排列组合为 34152。由上述的计算过程可以容易的逆推回来,具体过程如下:

    • 用 61 / 4! = 2余13,说明a[5]=2,说明比首位小的数有2个,所以首位为3。
    • 用 13 / 3! = 2余1,说明a[4]=2,说明在第二位之后小于第二位的数有2个,所以第二位为4。
    • 用 1 / 2! = 0余1,说明a[3]=0,说明在第三位之后没有小于第三位的数,所以第三位为1。
    • 用 1 / 1! = 1余0,说明a[2]=1,说明在第二位之后小于第四位的数有1个,所以第四位为5。
    • 最后一位自然就是剩下的数2啦。
    • 通过以上分析,所求排列组合为 34152。

    代码:

    #include<iostream>  
    #include<cstring>  
    #include<vector>
    #include<algorithm>
    using namespace std;  
    long int factory[]={1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; 
    void decontor(int x, int n)  {
        vector<int> v;
        vector<int> a;
        for(int i = 1; i <= n; i++) v.push_back(i);
        sort(v.begin(), v.end());
        for(int i = n-1; i >= 0; i--) {  
            int r = x % factory[i];
            int t = x / factory[i];
            x = r;
            a.push_back(v[t]);
            v.erase(v.begin()+t);
        }
        for(int i = 0; i < a.size(); i++) cout << a[i];                          
    }  
    int main()  
    {  
          int x, n;
        cin >> x >> n;
        decontor(x, n);   
        return 0;  
    }  
    作者:kindleheart
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    c#中this的一种特殊用法(extension method)
    Use a String.Format format and transform its output to its inputs?
    c#项目中遇到的add event 的一个小例子
    抽象类可以定义常量,接口中不可以定义常量
    c# 浅拷贝与深拷贝
    定制Dictionary
    c#中object字节问题
    编译过程知识的小补习
    抽象耦合
    控件集合属性遇到的问题
  • 原文地址:https://www.cnblogs.com/kindleheart/p/8749444.html
Copyright © 2011-2022 走看看