康托展開公式
X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,a為整數,並且0<=ai<i(1<=i<=n)。這就是康托展開。
康拓展開執行個體{1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按從小到大排列一共6個。123 132 213 231 312 321 。
代表的數字 1 2 3 4 5 6 也就是把10進位數與一個排列對應起來。
他們間的對應關係可由康托展開來找到。
如我想知道321是{1,2,3}中第幾個大的數可以這樣考慮 :
第一位是3,當第一位的數小於3時,那排列數小於321 如 123、 213 ,小於3的數有1、2 。所以有2*2!個。再看小於第二位2的:小於2的數只有一個就是1 ,所以有1*1!=1 所以小於321的{1,2,3}排列數有2*2!+1*1!=5個。所以321是第6個大的數。 2*2!+1*1!+1*0!就是康托展開。
再舉個例子:1324是{1,2,3,4}排列數中第幾個大的數:第一位是1小於1的數沒有,是0個 0*3! 第二位是3小於3的數有1和2,但1已經在第一位了,所以只有一個數2 1*2! 。第三位是2小於2的數是1,但1在第一位,所以有0個數 0*1! ,所以比1324小的排列有0*3!+1*2!+0*1!=2個,1324是第三個大數。代碼
const int PermSize = 12;long long factory[PermSize] = { 0, 1, 2, 6, 24, 120,720, 5040, 40320, 362880, 3628800,39916800 };long long Cantor(string buf) {int i, j, counted;long long result = 0;for (i = 0; i < PermSize; ++i) {counted = 0;for(j = i + 1; j < PermSize; ++j)if(buf[i] > buf[j])++counted;result = result + counted *factory[PermSize - i - 1];}return result;}
來源於百度百科