康拖展开式+逆康拖展开式

康拓展开式:
康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩,在组合数学中,其解决的是当前排列在全排列中的名次问题。简单来说,给定一个 n 位数的全排列,可根据康托展开公式确定其应是字典序中的第几个排列。由于康托展开计算的是某个全排列方式在该全排列集合中的字典序,其映射关系是唯一的,而且单调,因此映射关系是可逆的,故而当给定一个全排列的所有字符,以及某个字典序编号,可以利用逆康托展开得到相应的那个全排列。
总而言之就是求出该排列在全排列中排第几;
计算公式:
hahahahah
其中a[ i ] 表示的是原排列中其身后有多少个比它小的元素
代码如下:

void cantor(int str[],int n)
{
    int ans=0;
    for(int i=0;i<n;i++)
    {
        int num=0;
        for(int j=i+1;j<n;j++)
        {
            if(str[i]>str[j])
                num++;//计算其身后有多少个比它小的元素
        }
        ans+=num*fun(n-i+1);//fun函数是计算阶乘的
    }
}

逆康拖展开式:
如果已知 s = [“A”, “B”, “C”, “D”],X(s1) = 20,能否推出 s1 = [“D”, “B”, “A”, “C”] 呢?
  因为已知 X(s1) = a43! + a32! + a21! + a10! = 20,所以问题变成由 20 能否唯一地映射出一组 a4、a3、a2、a1?如果不考虑 ai 的取值范围,有
33! + 12! + 01! + 00! = 20
23! + 42! + 01! + 00! = 20
13! + 72! + 01! + 00! = 20
03! + 102! + 01! + 00! = 20
03! + 02! + 201! + 00! = 20
等等。但是满足 0 <= ai <= n-1 的只有第一组。可以使用辗转相除的方法得到 ai,如下图所示:

在这里插入图片描述
已知值求其式子,用辗转相除法得到各个位上的值
知道了a4、a3、a2、a1的值,就可以知道s1[0] 是子数组[“A”, “B”, “C”, “D”]中第3大的元素 “D”,s1[1] 是子数组 [“A”, “B”, “C”] 中第1大的元素"B",s1[2] 是子数组 [“A”, “C”] 中第0大的元素"A",s[3] 是子数组 [“C”] 中第0大的元素"C",所以s1 = [“D”, “B”, “A”, “C”]。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值