#includeusing康托展開是乙個全排列到乙個自然數的雙射,常用於構建雜湊表時的空間壓縮。 康托展開的實質是計算當前排列在所有由小到大全排列中的順序,因此是可逆的。namespace
std;
int num[100
],cnt;
void fun(int pos,int
n);int judge(int l,int
r);int
main()
int judge(int l,int
r)void fun(int pos,int
n)
for(int i=pos;i<=n;i++) }
令x為全排列中的次序,num為原陣列,n為全排列中數字的個數,
為num[j] (j>i)小於num[i]的個數。
則例:有(1,2,3,4,5)5個數的全排列中,計算34152的康托展開值。
通過定義可知,a[5] = 2 (1<3,2<3),a[4] = 2 (1<4,2<4),a[3] = 0 (無),a[2] = 1 (2<5),a[1] = 0 (無)。
又因為 n = 5,則x=2*4! + 2*3! + 0*2! + 1*1! + 0*0! = 61
所以在全排列中比34152小的有61個,即34152在全排列中排第62位(61+1=62)。
因為康托展開是乙個全排列到乙個自然數的雙射,所以可以通過61計算出34152。
有,得出
例:61/4! = 2...13 則a[5] = 2,num[5]=3
13/3! = 2...1 則a[5] = 2,num[4]=4
1/2! = 0...1 則a[5] = 0,num[4]=1
1/1! = 1...0 則a[5] = 1,num[2]=5
則num[1]為剩下的數,num[1]=2
所以前面有61個排列,即第62個全排列為34152。
26458173的下乙個全排列為26458317。
步驟:①從後往前找到第乙個
的位置 (即樣例中為1<7)
②從後往前找到第乙個大於
的數 x ,交換
和 x的位置 (
=1,x=3),得到26458371
③將位置 i 以後的數反轉,得到26458317。
上乙個全排列的求法與下乙個全排列類似,自行解決。
康托展開 全排列
今天找到了一篇非常好的介紹康托展開的文章!其核心是這一張圖 letter 儲存所需字母表 void initletter 初始化字母表 int fact int n 階乘 return result void output vector v 輸出生成的結果 cout endl void divisi...
康托展開 全排列
對於n個數的全排列,共有n!中排列方式,如何求某乙個序列在整個排列中的次序 從小到大 以9的全排枚舉例 842697513是1 9全排列的第幾個?高中數學排列組合問題,只需要做到不重不漏 首先看第一位為8,那麼第一位為1 7的全排列都比它小,共有7 8!個。在第一位為8的情況下,其次看第二位為4,那...
全排列康托展開
n個元素有n 個不同的排列。將這n 個排列按字典序排列,並編號為0,1,n 1。每個排列的編號為其字典序值。例如,當n 3時,6 個不同排列的字典序值如下 0 1 2 3 4 5 123 132 213 231 312 321 任務 給定n 以及n 個元素的乙個排列,計算出這個排列的字典序值,以及按...