zoukankan      html  css  js  c++  java
  • 全排列_获取第几个排列_获取是第几个排列__康托展开,逆康托展开

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    // 适用范围: int: n --> [0, 15]     long long: n--> [0, 21]
    class Cantor_Expansion{
    public:
        // 阶乘数组  
        const int fac[16] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 1932053504, 1278945280, 2004310016}; 
        vector<int> cve, tve;
        int cn;
        
        // 下标从0开始, 返回排列在全排列中的次序.
        // @ arr[]  排列数组
        // @ n     排类长度 
        int Getid(int arr[], int n)    {
            int i, j, cnt, res = 0;    
            for (i=0; i<n; ++i) {
                cnt = 0;
                for (j=i+1; j<n; ++j) 
                    if (arr[j] < arr[i]) cnt++;
                res += fac[n-i-1] * cnt;
            } 
            return res;
        }
        
        // 如果要返回排列 必须初始化 
        // @arr[]  初始化数组, 下标[0, n-1]
        // @n      长度 
        void init(int arr[], int n) {
            int i;
            cve.clear();
            for (i=0; i<n; ++i) 
                cve.push_back(arr[i]); 
            sort(cve.begin(), cve.end());
            cn = n;
        }
        
        // 返回排第k的排列  排列时从 0开始的. [0, n!-1] 
        // @arr[] 保存答案的数组  下标从0开始 
        // @id    要获得的排列的名次 
        int GetArr(int arr[], int id) {
            int i, t, cnt = 0;
            tve.assign(cve.begin(), cve.end());
            for (i=cn-1; i>=0; --i) {
                arr[cnt++] = tve[id / fac[i]];
                tve.erase(tve.begin()+(id / fac[i])); 
                id = id % fac[i];
            }
        }
    }ct; 
    
    int main()
    { 
        
        // 逆展开 获取排序 
        int i, arr[5];
        int tarr[] = {3, 4, 1, 5, 2};
        ct.init(tarr, 5);
        ct.GetArr(arr, 1);
        for (i=0; i<5; ++i) 
            printf("%d ", arr[i]);
        
        // 顺展开获取id 
        printf("
    %d", ct.Getid(tarr, 5));
        
        return 0;
    }
  • 相关阅读:
    标题栏外区域拖动窗体
    搜索引擎技术核心揭密
    用C#实现木马程序(转载)
    DotNet里的控件数组
    RECORDNUMBER应用之控制每页显示行数及隔行换色
    搜索引擎技术学习
    VB里面操作Excel(居然比C#强)
    第三代搜索引擎技术与P2P
    C# 用API播放声音
    如何判断ExecuteScalar()得到的结果是否有记录
  • 原文地址:https://www.cnblogs.com/cgjh/p/9475787.html
Copyright © 2011-2022 走看看