康托逆展开和康托展开的逆运算

百度百科有一些说明 但很难看懂 我尽可能用简单的语言来说明

学会使用康托展开后就能方便地解决一系列的问题

一、康托展开

对于一个集合{1,2,3,4,...,n}的从小到大排序(或者从大到小,与从小到大类似,这里只说前者)的全排列 显然它有n!项

用自然数1,2,...,n!与之一一对应,这是一种对应法则。


这个法则理解起来并不容易,还是用一些例子来说明吧

例1 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕

(1)找出45231在这个排列中的顺序

比4小的数有3个
比5小的数有4个但4已经在之前出现过了所以是3个
比2小的数有1个
比3小的数有两个但2已经在之前出现过了所以是1个
比1小的数有0个

那么45231在这个排列中的顺序是3*4!+3*3!+1*2!+1*1!+0*0!+1=94

(2)找出35142在这个排序中的顺序

比3小的数有2个
比5小的数有4个但3已经在之前出现过了所以是3个
比1小的数有0个
比4小的数有3个但2,3已经在之前出现过了所以是1个
比2小的数有1个但1已经在之前出现过了所以是0个

那么35142在这个排序中的顺序是2*4!+3*3!+0*2!+1*1!+0*0!+1=68

例2 {1,2,3,4,5,6}的全排列,并且已经从小到大排序完毕

找出423615在这个排序中的顺序

比4小的数有3个
比2小的数有1个
比3小的数有2个但2已经在之前出现过了所以是1个
比6小的数有5个但4,2,3已经在之前出现过了所以是2个
比1小的数有0个
比5小的数有4个但1,2,3,4已经在之前出现过了所以是0个

那么423615在这个排序中的顺序是3*5!+1*4!+1*3!+2*2!+0*1!+0*0!+1=395

看了3个例子大概怎么个运算规则应该是能理解了吧 用个一般些的表达式是
对于{1,2,3,...,n}生成的已经从小到大排序好的全排列

x=a[n]*(n-1)!+a[n-1]*(n-2)!+...a[1]*0!
a[m]代表比在第m位的数字小并且没有在第m位之前出现过的数字的个数(以个位数为第1位)

x代表比这个数小的数的个数,所以这个数的顺序就是x+1

注:
1.易知a[1]=0
2.这个版本和百度百科看见的应该有些不同,主要是我没有怎么理解那个式子就自己总结了下

二、康托展开的逆运算
这个内容我没有在网上找到,不过实现起来并不麻烦,主要还是自己的话应该有很多不严谨之处敬请谅解

这个方法还是用例子来说比较好
例1 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕
(1)找出第96个数
首先用96-1得到95
用95去除4! 得到3余23
用23去除3! 得到3余5
用5去除2!得到2余1
用1去除1!得到1余0

有3个数比它小的数是4
所以第一位是4
有3个数比它小的数是4但4已经在之前出现过了所以是5(因为4在之前出现过了所以实际比5小的数是3个)
有2个数比它小的数是3
有1个数比它小的数是2

最后一个数只能是1
所以这个数是45321

(2)找出第16个数
首先用16-1得到15
用15去除4!得到0余15
用15去除3!得到2余3
用3去除2!得到1余1
用1去除1!得到1余0

有0个数比它小的数是1
有2个数比它小的数是3 但由于1已经在之前出现过了所以是4(因为1在之前出现过了所以实际比4小的数是2)
有1个数比它小的数是2 但由于1已经在之前出现过了所以是3(因为1在之前出现过了所以实际比3小的数是1)
有1个数比它小得数是2 但由于1,3,4已经在之前出现过了所以是5(因为1,3,4在之前出现过了所以实际比5小的数是1)

最后一个数只能是2
所以这个数是14352

这个东西我想不出什么特别好的一般表达式,不过用上面例子的方法应该足够了

转载地址:

http://hi.baidu.com/wcj1024/blog/item/c0f6aaedec99d5dcb21cb152.html

 

 
已有7人分享了这篇文章:
johnsondzl
Ta的分享
migicyang
Ta的分享

posted on 2012-04-23 22:51  江财小子  阅读(236)  评论(0编辑  收藏  举报