写在前面
康托展开 是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。
通俗一点来说就是 每一个排列 都代表 一个自然数
表示他在 所有排列中 的 排名
很明显可以用暴力搜索,此处不过多阐述
正文
主要讲解康托展开的实现以及逆康托展开的实现,推荐习题 P1088【火星人】
公式
康托展开 :
X
=
a
n
(
n
−
1
)
!
+
a
n
−
1
(
n
−
2
)
!
+
.
.
.
+
a
1
⋅
0
X = a_n(n - 1)! + a_{n - 1}(n - 2)! +... + a_1 · 0
X=an(n−1)!+an−1(n−2)!+...+a1⋅0
其中,
a
i
a_i
ai 为整数,并且
0
<
a
i
<
i
,
1
<
i
<
n
0 < a_i < i ,1 < i < n
0<ai<i,1<i<n
a
i
a_i
ai 表示原数的第i位在当前未出现的元素中是排在第几个
举个例子
康托展开
就举个例子吧
n
=
5
n = 5
n=5
{
1
,
4
,
2
,
5
,
3
1, 4, 2, 5, 3
1,4,2,5,3} 是一个排列
第一位有
n
n
n 种选择,然而第二位只有
n
−
1
n - 1
n−1 种选择,第三位有
n
−
2
n - 2
n−2 种选择,第四位有
n
−
3
n - 3
n−3 种选择,第五位只有
n
−
4
n - 4
n−4 种选择
乘起来刚好是
n
!
n!
n!
于是每一位都对应一个进制, 第一位是
n
n
n 进制,第二位是
n
−
1
n - 1
n−1 进制,
.
.
.
...
... ,第五位是
n
−
4
n - 4
n−4 进制,于是得到规律:第
i
i
i 位的进制 是
n
−
i
+
1
n - i + 1
n−i+1
这时我们使用康托展开即可得到一个 u n k n o w n unknown unknown 进制数(因为每一位的进制不一样)
流程如下 :
~~~~~~~~
第五位 :1 在 剩下的数 {1 ,2 ,3 ,4 ,5} 里排名为 : 0 ,第一位为 0
~~~~~~~~
第四位 :4 在 剩下的数 {2 ,3 ,4 ,5} 里排名为 : 2 ,第二位为 2
~~~~~~~~
第三位 :2 在 剩下的数 {2 ,3 ,5} 里排名为 : 0 ,第三位为 0
~~~~~~~~
第二位 :5 在 剩下的数 {3 ,5} 里排名为 : 1 ,第四位为 1
~~~~~~~~
第一位 :第五位为 0
可得
{
02010
}
u
n
k
n
o
w
n
{\{02010\}}_{unknown}
{02010}unknown,也可以算出来自然数
X
X
X
逆康托展开
原理 : 一开始已经提过了,康托展开是一个全排列到一个自然数的双射,因此是可逆的。
假如有这么一个数 { 23010 } u n k n o w n {\{23010\}}_{unknown} {23010}unknown ,求他映射的全排列
流程倒着来即可,自然数的话见康托展开
~~~~~~~~
第一位 : {1 ,2 ,3 ,4 ,5} 里排名为 2 的是 3 ,第一位为 3
~~~~~~~~
第一位 : {1 ,2 ,4 ,5} 里排名为 3 的是 5 ,第二位为 5
~~~~~~~~
第一位 : {1 ,2 ,4} 里排名为 0 的是 1 ,第三位为 1
~~~~~~~~
第一位 : {2 ,4} 里排名为 1 的是 4 ,第四位为 4
~~~~~~~~
第一位 : {2} 里排名为 0 的是 2 ,第五位为 2
可得排列 3 5 1 4 2 {3~~5~~1~~4~~2} 3 5 1 4 2
后记
错误请帮忙指出
谢谢大家
——2020.9.13