1.中介数逆推原排列:上一章我们讲到了中介数,通过一个排列可以很方便地求数它的中介数,通过中介数也可以很方便地求出排位序号。但是通过中介数逆推原排列就不是那么容易了。因为我们每求一位数,都需要对比其前面所有的数来获取他的定位,以上一章{ 3,4,5,6,7,2,1 }为例,得到的{2,2,2,2,2,1}中介数,第一位我们可以直接得出3,第二位本应也是3,但是考虑前面已经有3了,所以第二位就只能是4,以此类推……即:如果之前存在某排位i小于等于当前排位,那么当前排位所对应的数需要再加上1

2.原中介数逆推求原排列代码(错误版):

int* get_permutation(int medium[], int n)
{int* temp = new int[n + 1];for (int i = 0; i <= n; i++){temp[i] = i == n ? 1 : medium[i] + 1;}for (int i = 0; i <= n ; i++){for (int j = i - 1; j >= 0; j--){if ((medium[j] <= (i == n ? 1 : medium[i]))||(temp[j] <= temp[i])){temp[i]++;}}} return temp;
}

解释一下这种思路:以{ 7,6,8,3,4,5,1,2 }为例,其中序数为{6,5,5,2,2,2,0}

①第一位是7

②第二位是6

③第三位原本应为6,但是其与第二位中序数相等(medium[j] <= (i == n ? 1 : medium[i]),故加1。加完1后第三位原本应为7,但又与第一位的7真实数相等(temp[j] <= temp[i]),故第三位为8

④第四位为3

⑤第五位为3,但因为与第四位中序数相等(medium[j] <= (i == n ? 1 : medium[i]),故为4

⑥第六位为3,且此时小于第五位的真实数(4),但是其原本的中序数等于第五位,故其为+1为4,再与第四位对比,变成5

⑦第七位为1,

⑧第八位为1,但与第七位相等,故为2

也就是说,我们定位当前位i不但要考虑其原始中序数值(medium[j] <= (i == n ? 1 : medium[i])的关系,还要经过逆推考虑影响后,其真实数值的关系(temp[j] <= temp[i])

看似没有什么问题,我们再看一组测试样例:{ 3,6,4,7,5,2,1 },其中中序数为{2,4,2,3,2,1}

①第一位是3

②第二位原本应是5,但大于第一位,故是6

③第三位原本应是3,但大于第一位,故是4

④第四位原本应是4,但等于第三位,故是5,然后小于第二位,继续向前,大于第一位,故为6

注意!!第四位竟然是6,但实际上此时已经与第二位冲突了。

这里我们发现了,我们无法确定后续的比较当前点i能走到什么值,所以当我们判断某一个点j的时候是无法确定j点真实值是否小于i点的。比较简单的解决方式是保证遍历的时候是从小到大进行比对,这样我们就要将在此之前确定好真实值的数组进行递减排序。

代码如下:

int* get_permutation(int medium[], int n)
{int* temp = new int[n + 1];int* permutation = new int[n + 1];for (int i = 0; i <= n; i++){permutation[i]=temp[i] = i == n ? 1 : medium[i] + 1;}for (int i = 0; i <= n ; i++){for (int j = i - 1; j >= 0; j--){if (temp[j] <= temp[i]){temp[i]++;permutation[i]++;}else{break;}}sort(temp,temp + i+1, greater<int>());} return permutation;
}

所以看出,这种中介数求原排列实际上非常的复杂。

外部调用:

int main()
{int A[] = { 7,6,8,3,4,5,1,2 };int n = sizeof(A) / sizeof(A[0]);int *medium = get_permutation_medium(A, n);Print(medium, n-1);//中序数长度比原排列小1int *B = get_permutation(medium, n - 1);Print(B,n);//int rank =get_permutation_rank(medium, n);//printf("%d\n",rank);system("pause");return 0;
}

3.运行截图:

4.参考文档

https://wenku.baidu.com/view/8c79a2facc17552706220880.html

全排列及相关扩展算法(四)——原始中介数通过逆推求原排列算法相关推荐

  1. 全排列及相关扩展算法(五)——递增(递减)进位制数求原排列算法

    1.引入原因:通过上一章我们意识到通过原始中介数求原排列并不是那么的方便,于是我们延伸出几种新的中介数算法来方便计算原排列. 2.递增进位制数法:递增进位制是指数字的进制随着数字位置的不同递增,一般的 ...

  2. 全排列及相关扩展算法(六)——全排列最蛋疼的算法:邻位对换法

    1.引入原因:在此之前我们实现全排列本质上都是采用单向交换的思路,当交换到末端便要回溯至上一层面,如果我们采用双向的交换,便可以不断地交换下去,于是产生了邻位对换法.邻位对换法在找下一个排列的方法上在 ...

  3. 全排列邻位对换法c语言算法,全排列及相关扩展算法(六)——全排列最蛋疼的算法:邻位对换法...

    1.引入原因:在此之前我们实现全排列本质上都是采用单向交换的思路,当交换到末端便要回溯至上一层面,如果我们采用双向的交换,便可以不断地交换下去,于是产生了邻位对换法.邻位对换法在找下一个排列的方法上在 ...

  4. 全排列及相关扩展算法(三)——利用中介数求排列在字典序排位算法

    1.中介数的定义及作用:很多时候,我们要通过一个排列得出它的字典序中的位置(序号),比如1234567应该排在第0位(开始位),1234576应该排在第1位,7654321排在第7!-1=5039位. ...

  5. 全排列及相关扩展算法(七)——组合数的字典序(另含全章代码整理)

    1.引入概念:要列出一个集合{1,2,3,4}的所有子集是很容易的,我们可以按照二进制数的顺序,0000,0001,0010,0011,0100,0101,0110,0111......来表示我们要取 ...

  6. 全排列及相关扩展算法(二)——求字典序下一组排列及全排列算法

    1.字典序排列的定义:为了便于理解,以数字为例,对于数字1.2.3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的.例如对于5个数字的排列 12354和12345,排 ...

  7. 全排列及相关扩展算法(一)——基础的回溯递归实现全排列算法

    1.全排列的定义和公式: 从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列.由排列的定义,显然不同的顺序是一个不同的排列.从n个元素中取m个元素 ...

  8. 算法之地推算法(逆推法)

    逆推法实例:  小龙,每个月可以取出1000元.若在第48月小龙大学毕业时连本带息要取1000元,年利率是0.0171,那么至少要存多少钱? 则先要求出第47个月时银行存款的钱数   第47个月月末存 ...

  9. 基于matlab的捷联惯导算法设计及仿真,基于 Matlab 的捷联惯导算法设计及仿真1doc.doc...

    基于 Matlab 的捷联惯导算法设计及仿真1doc 基于 Matlab 的捷联惯导算法设计及仿真1 严恭敏 西北工业大学航海学院,西安 (710072) E-mail:yangongmin@163. ...

最新文章

  1. 卓越的TurboGate邮件网关企业邮箱的安全保障
  2. Vue 脚手架生成的项目结构分析||Vue 脚手架的自定义配置
  3. 从证书中导出公钥并存放到项目中
  4. 使用C#和Excel进行报表开发(五)-操作单元格边框和颜色 【转】
  5. 监控组策略应用----组策略结果
  6. npp夜光数据介绍 viirs_对 VIIRS/NPP 夜光数据的解读
  7. 2021年下半年软件设计师考试下午题
  8. endnote修改正文中参考文献标注_Endnote之文献标注
  9. MobaXterm复制黏贴快捷键
  10. 国开计算机专业英语答案,国开电大计算机专业英语阅读(河北)形考三参考答案...
  11. C#操作word定位光标
  12. php活动倒计时代码,JavaScript实现活动倒计时效果的代码分享
  13. Kali无线渗透加油破解无线
  14. 2022国赛论文及可运行代码
  15. catti 三笔 计算机专业,catti三级笔译含金量高吗
  16. 小球碰壁反弹加分_js中小球碰壁反弹
  17. OC与swift相互调用
  18. 网站一个月的花费是多少钱?
  19. Vue电商系统后台API接口
  20. 【LInux软件--星际译王安装、词库下载】

热门文章

  1. 9 WM配置-主数据-定义物料分阶段的范围(Staging Area)
  2. springboot 上传图片大小_springboot 文件上传大小配置的方法
  3. 【Pytorch】model.train()和model.eval()用法和区别,以及model.eval()和torch.no_grad()的区别
  4. 递归列出文件下的文件信息,迭代器
  5. [Unity][FlowCanvas][NodeCanvas] ForEach 不适合连接 Wait,FSM 的 SubFlowScript 接受不到事件
  6. webserver之日志系统
  7. python的标准类型内建函数_Python内建函数
  8. PhotoShop制作空心圆角矩形
  9. 解决:vue文本识别 “ \n ” 的换行问题(完整案例说明)
  10. 多功能拼团商城源码-带优惠券功能+自适应移动端+对接免签约支付