逆康拓展开展开
逆康拓展开和康拓展开差不多,
因为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; }