算法分析与设计之排列的字典序问题
来源:互联网 发布:nginx 判断是否有参数 编辑:程序博客网 时间:2024/05/16 19:40
问题描述:n个元素{1,2,3...n}有n!种不同的排列。将这n!个排列按字典序排列,并编号0,1,2,3...n!-1。每个排列的编号为其字典序值。例如,当n=3时,有6个不同排列的字典序如下:
字典序值012345排列123132213231312321算法设计:给定n以及n各元素{1,2,3...n}的一个排列,计算出这个排列的字典序值,以及按字典序排列的下一个排列。
问题分析:比较简单的想法就是就是将n个元素进行排列有n!中组合,然后将这些数进行排序。但是这样存在,效率低下、存储空间消耗巨大的问题。如果运用递归和分治策略来解决问题就会简单的多。
具体步骤:为了求排列对应的序号,只要该序列到第一个序列即0,1,2,3…n-1所需要移动的次数。移动原则是a[i]从大到小移动,对于每一个数字a[i],若i前面比a[i]小的个数正好是a[i]-1个,则这个数不需要向后移动以达到目标序列,否则i后面必然有a[i]-b[i]-1个比a[i]小的数,只要把a[i]移动到比自己小的数后面才能使得移动中的序列正向目标前进。因此只要求出每个数的移动次数,然后相加就是该序列的位置。即每个数到正确位置需要移动的次数为(n-i-1)!*(a[i]-b[i]-1)。
程序代码:
#include<stdio.h>#include<stdlib.h>void SWAP(int * a, int * b){ long long t; t = *a; *a = *b; *b = t;}int main(){ int n,i,k,j,t,order[100]; int lis,f[100],mid,h; f[0]=1; for(i=1;i<=22;i++) f[i]=f[i-1]*i;printf("请输入元素的个数,以及一个序列\n"); if(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) scanf("%d",&order[i]); if(n==1) printf("0\n1\n"); else if(n>=2) { lis=0; for(i=0,k=n-1;i<n-1;i++,k--) { t=0; for(j=0;j<i;j++) if(order[j]<order[i]) t++; lis+=(order[i]-1-t)*f[k]; } printf("该序列是第%d个\n",lis); for(i = n-2; i >= 0; i--) { if(order[i] < order[i+1]) { j = i; for(k = n-1; k > j; k--) { if(order[k] > order[j]) { mid = j+(n-j)/2; SWAP(&order[j], &order[k]); for(j++, h = 1; j <= mid; j++, h++) SWAP(&order[j], &order[n-h]); } } break; } } printf("该序列的下一个序列是:\n"); for(i=0; i < n-1; i++) printf("%d ",order[i]); printf("%d\n",order[i]); } } return 0;}运行截图:
总结:
在排列的字典序问题上,在求某个序列是字典序的第几个时,要掌握规律,即(n-i-1)!*(a[i]-b[i]-1)。某个序列移动到最小序列即1234…n时所移动的次数即该序列所在位置,而移动次数又可以转换为每个位置上的数移动到正确位置的次数的和。由此即可求出某个序列在字典序的什么位置。在求解序列的下一个序列时,其核心思想是从数组尾部开始找相邻两个元素,满足order[i]<order[i+1],再从数组尾部开始找第一个大于order[i]的数order[k](k>i),交换order[i]和order[k],order[i+1]~order[n-1]进行逆向重排。
- 算法分析与设计之排列的字典序问题
- 排列的字典序问题 算法与设计
- 【算法分析与设计】全排列问题
- 关于Johnson-Trotter和字典序排列在《算法设计与分析基础》中的论述
- 【算法设计与分析】递归与分治----2.4 排列问题
- 全排列问题问题的两种算法--递归与字典序
- 全排列算法的字典序排列
- 字典序排列的算法
- 算法设计与分析 全排列的递归实现算法
- 排列的字典序问题
- 排列的字典序问题
- 排列的字典序问题
- 排列的字典序问题
- 排列的字典序问题
- 排列的字典序问题
- 排列的字典序问题
- 排列的字典序问题
- 排列的字典序问题
- struts2-3
- [HAL库学习之路]9.输入捕获
- java冒泡排序,选择排序
- 产品设计-电商中商品体系
- MarkDown 写博客时的一些符号操作
- 算法分析与设计之排列的字典序问题
- 前端项目引入苹方字体
- Hibernate学习---缓存机制
- 什么玩意?快读快写浮点型数据?
- 求素数
- 期末作业系列之设计模式
- 【深度分析】Docker的link机制
- JAVA byte取值范围表达理解
- Fatal error compiling: java.lang.NoSuc hFieldError??