康托展開與康托展開的逆運算

2021-08-10 15:28:00 字數 1058 閱讀 8889

康托展開用來求陣列是該全排列的第幾項,康托展開的逆運用用於求全排列的第幾個排列。

已知對於1-n個數的全排列,總共的可能是n!種。對於乙個已知的數列比如45321,在第一項是4時,表示第一項在此之前已經填放過1 2 3了,而後面的第二項至第五項則又是乙個全排列,那麼此時的排列數就是3 * 4 !;第二位是5,則在放入5之前第二項已經放過1 2 3了,那麼排列數再加上3 * 3!;依次類推,最終答案為:∑n

i=1=

a[i]

∗(n−

i)!其中a[i]表示第i項前比它小的沒出現過的數字的個數。

易證,a[

1]∗(

n−1)

!>∑n

i=2=

a[i]

∗(n−

i)!,因此給定乙個r表示是全排列的第r項,由r/

(n−1

)!得到a[1],則第一位數即a[1] + 1;在r中減去(a[1] + 1) * (n -1)!,同理可以由$r / (n-2)!&得到a[2];依次類推,最後得到整個排列。

要注意的是 0! = 1

**模版:

ll fac[20]; //階乘

void getfac()

ll cantor(int *a,int

len) //康托展開求a是全排列第幾項,a從1開始

; for(int i=1;i<=len

-1;i++)

return ret +1;

}void _cantor(ll r,int

len) //康托展開逆運算求第r個排列

,a[20];

for(int i=1;i<=len;i++)

vis[j] =1;

a[i] = j;

}for(int i=1;iprintf("%d ",a[i]);

printf("%d\n",a[len]);

}

康托展開及其逆運算

康托展開的wiki介紹 申明 1.用c語言實現。2.for中的i,j定義適用於c99標準,gcc編譯要新增 std c99選項。或者將i,j的定義放到for之前的外部作用域。3.逆運算使用了c99標準的vla,即變長陣列,只能用於區域性作用域,且宣告時不能初始化 也可以不用vla,使用malloc等...

康托展開與康托逆展開

康托展開,用人話說出來.就是把乙個陣列的多種排序情況對應用數字表示出來 公式 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,在...

康托展開與逆康托展開

1.康托展開 康托展開是乙個全排列到乙個自然數的雙射,常用於構建hash表時的空間壓縮。設有n個數 1,2,3,4,n 可以有組成不同 n 種 的排列組合,康托展開表示的就是是當前排列組合 例如對於 1 4 的乙個全排列,1,2,3,4 和 4,3,2,1 分別為第乙個和最後乙個排列。康托展開公式為...