康拓展开

康拓展开

康拓展开可以用于求某个排列是全排列中的第几个
原理:X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! (a[i]为整数,并且0 <= a[i] <= i, 0 <= i < n, 表示在当前未出现的元素中排第几个)
举例说明:比如我想知道4312是{1,2,3,4}的全排列的第几个,可以:3*3!+2*2!+0*1!+0*0!=22,得知在其前面的有22种排列,可知其是第23个排列。
因为对于第1位(即4),比4小且未出现过的数有3个,后面还有3位,共3*3!种组合,对于第2位,第3位,第4位同理,累加即可知道在其前面的排列共有多少种。
代码表示:

int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};  
int cantor(int *a, int n)
{
    int res = 0;
    for (int i = 0; i < n; ++i) {
        int cnt = 0;  // 在当前位之后小于其的个数
        for (int j = i + 1; j < n; ++j) {
            if (a[j] < a[i])
                cnt++;
        }
        res += FAC[n - i - 1] * cnt; // 康托展开累加
    }
    return res;  // 康托展开值
}
原文地址:https://www.cnblogs.com/orangee/p/9406382.html