簡要介紹康託展開

蚩尤煜發表於2020-10-11

本篇文章並不會詳細講解康託展開的數學原理,有興趣的朋友可以另行尋找。

康託展開

作用:判斷這個數在其各個數字全排列中從小到大排第幾位。比如 132,在1、2、3的全排列中排第2位。


首先定義一個特殊的進位制:0! 1! 2! 3! 4! ...

即——1 1 2 6 24 ...

可類比其他進位制,如十進位制:

1 10 100 1000 ...

則312=(2*1 + 1*10 + 3*100)

某個排列的位置演算法: ∑(比這位上的數小的數的個數 * 這位數在排列中從右到左的位數) + 1 例子:

2431 = (1*6 + 2*2 + 1*1 + 0*1) + 1 = 12

312 = (2*2 + 0*1 + 1*1) +1 = 5

312的驗證:

①123

②132

③213

④231

⑤312

⑥321

 

程式碼:

//階乘0!~n!的陣列,此處n=9
 static const int FAC[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
 ​
 /*
     康託展開
     引數:存放某個全排列的num[]陣列,如:num[]={3,1,2};全排列數字的個數,像前面         的312的n就等於3
     返回值:返回這個已知全排列在全排列中的位置名次
 */
 int KT(int num[],int n)
 {
     int ans=1,temp; //temp為暫存前面比當前位小的個數
     for(int i=0;i<n;i++)
     {
         if(i==0)
         {
             ans=ans+(num[i]-1)*FAC[n-1];
         }
         else
         {
             temp=num[i]-1;
             for(int j=0;j<i;j++)
             {
                 if(num[j]<num[i])
                     temp--;
             }
             ans=ans+temp*FAC[n-1-i];
         }
     }
     return ans;
 } 

 

相關文章