逆康拓展开展开

逆康拓展开和康拓展开差不多,

因为X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! ,其中a[i]为当前未出现的元素中是排在第几个(从0开始)。这就是康托展开。康托展开可用代码实现。


X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0![1] 


根据康拓展开 反着来,

  比如 :

例1 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕
(1)找出第96个数
首先用96-1得到95
用95去除4! 得到3余23
有3个数比它小的数是4
所以第一位是4
用23去除3! 得到3余5
有3个数比它小的数是4但4已经在之前出现过了所以第二位是5(4在之前出现过,所以实际比5小的数是3个)
用5去除2!得到2余1
有2个数比它小的数是3,第三位是3
用1去除1!得到1余0
有1个数比它小的数是2,第二位是2
最后一个数只能是1
所以这个数是45321
原理很简单


来个代码

int* uncantor(int x, int k)
{
    int res[100];
    int i, j, l, t;
    bool h[100]= {0};
    for (i = 1; i <= k; i++)
    {
        t = x / faction[k - i];
        x -= t * faction[k - i];
        for (j = 1, l = 0; l <= t; j++)
            if (!h[j])
                l++;
        j--;
        h[j] = true;
        res[i - 1] = j;
    }
    return res;
}


posted @ 2016-04-17 20:47  Code-dream  阅读(228)  评论(0编辑  收藏  举报