康托展開與康托逆展開

2022-07-26 03:24:13 字數 1453 閱讀 3505

康托展開,用人話說出來..就是把乙個陣列的多種排序情況對應用數字表示出來

公式:x = a[i] * (n-1)! + a[i-1] * (n-2)! + … + a[1] * 0!

其中a[i]表示後面比該元素小的元素的個數

舉個例子,有5個數1 2 3 4 5

共有5個元素,所以一共有5!種排序方法

如果用康托展開序列35142

第乙個元素是3,在後面的序列中,有2個比3小的,所以ans += 2 * 4!

第二個元素是5,在後面的序列中,有3個比5小的,所以ans += 3 * 3!

第三個元素是1,在後面的序列中,有0個比1小的,所以ans += 0 * 2!

第四個元素是4,在後面的序列中,有1個比4小的,所以ans += 1 * 1!

第五個元素是2,在後面的序列中,有0個比2小的,所以ans += 0 * 0!

所以序列35142用康托展開後,為ans = 2 * 4! + 3 * 3! + 0 * 2! + 1 * 1! + 0 * 0! = 67

康托展開的**:

#include #include #include #include int factor[11];

int encode(int permutation, int, int a);

int main()

int encode(int permutation, int n, int a)

int sum = 0;

for(i=0; i<=n-1; i++)

sum += a[i] * factor[n-i-1];

return sum;

}

理解了康托展開,逆展開的思路就比較容易理解了。

已知5個元素 1, 2, 3, 4, 5

展開值ans = 67

怎麼求它的序列呢?

1. 67 / 4! = 2 餘 19

2. 19 / 3! = 3 餘 1

3. 1 / 2! = 0 餘 1

4. 1 / 1! = 1 餘0

5. 0 / 0! = 0 餘0

通過輾轉相除,我們可以求得a[5] = 2, a[4] = 3, a[3] = 0, a[2] = 1, a[1] = 0

那麼,序列的第乙個值便可求得,在五個元素內,有2個元素比它小,所以是3

第二個元素:除去3後,還有元素1,2,4,5,後面共有3個元素比它小,所以是5

第三個元素:除去3和5後,還有元素1,2,4,後面共有0個元素比它小,所以是1

第四個元素:除去1,3,5,還有元素2,4,後面有1個元素比它小,所以是4

第五個元素:除去1,3,4,5,還有元素2,後面有0個元素比它小,所以是2

這樣,我們就將康托展開值逆展開了,序列為3,5,1,4,2

康托展開 康托逆展開

x a n n 1 a n 1 n 2 a i i 1 a 1 0 其中a i 為當前未出現的元素中是排在第幾個 從0開始 這就是康托展開。康托展開可用 實現。編輯 把乙個整數x展開成如下形式 x a n n 1 a n 1 n 2 a i i 1 a 2 1 a 1 0 其中a i 為當前未出現的...

康托展開 逆康托展開

康托展開 問題 給定的全排列,計算出它是第幾個排列 求序列號 方法 康托展開 對於乙個長度為 n 的排列 num 1 n 其序列號 x 為 x a 1 n i a 2 n 2 a i n i a n 1 1 a n 0 其中a i 表示在num i 1 n 中比num i 小的數的數量 includ...

康托展開 逆康托展開

用途 康托展開是一種雙射,用於排列和整數之間的對映,可用於排列的雜湊 康托展開 公式 i n1pi i 1 sum limits p i i 1 i n 1 pi i 1 其中p ip i pi 為第i ii個數構成的逆序的個數,n為排列數的個數 例 排列 2134 i n1pi i 1 sum l...