全排列生成算法之字典序
来源:互联网 发布:独角仙 数码兽数据库 编辑:程序博客网 时间:2024/05/16 12:22
算法描述的参考链接:http://blog.csdn.net/joylnwang/article/details/7064115
使用字典序输出全排列的思路是,首先输出字典序最小的排列,然后输出字典序次小的排列,……,最后输出字典序最大的排列。这里就涉及到一个问题,对于一个已知排列,如何求出其字典序中的下一个排列。
这里给出算法步骤:
对于排列a[1...n],找到所有满足a[j]<a[j+1](0<j<n-1)的j的最大值,即为i。如果这样的i不存在,则说明当前排列已经是a的所有排列中字典序最大者,所有排列输出完毕。a[i+1]...a[n]为降序排列的。
在a[i+1...n]中,寻找满足这样条件的元素k,使得在所有a[k]>a[i]的元素中,a[k]取得最小值。也就是说a[i]<a[k],a[i]>a[k+1]。
交换a[i]与a[k].
对于a[i+1...n],反转该区间内元素的顺序。也就是说a[i+1]与a[n]交换,a[i+2]与a[n-1]交换,……,这样就得到了a[1...n]在字典序中的下一个排列。
如何得到21453
1.从尾部找第一个a[i]<a[i+1]的位置
找到4
2.从4往后找到最后一个大于4的数5
3.交换4和5,变为21543
4.反转5后面区间内的元素,21534
使用字典序输出全排列的思路是,首先输出字典序最小的排列,然后输出字典序次小的排列,……,最后输出字典序最大的排列。这里就涉及到一个问题,对于一个已知排列,如何求出其字典序中的下一个排列。
这里给出算法步骤:
对于排列a[1...n],找到所有满足a[j]<a[j+1](0<j<n-1)的j的最大值,即为i。如果这样的i不存在,则说明当前排列已经是a的所有排列中字典序最大者,所有排列输出完毕。a[i+1]...a[n]为降序排列的。
在a[i+1...n]中,寻找满足这样条件的元素k,使得在所有a[k]>a[i]的元素中,a[k]取得最小值。也就是说a[i]<a[k],a[i]>a[k+1]。
交换a[i]与a[k].
对于a[i+1...n],反转该区间内元素的顺序。也就是说a[i+1]与a[n]交换,a[i+2]与a[n-1]交换,……,这样就得到了a[1...n]在字典序中的下一个排列。
如何得到21453
1.从尾部找第一个a[i]<a[i+1]的位置
找到4
2.从4往后找到最后一个大于4的数5
3.交换4和5,变为21543
4.反转5后面区间内的元素,21534
附上我的代码:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int maxn=15;int a[2][maxn];int flag=0;int n,cnt;void init() { cnt=1; printf("the full permutation of %d is\n",n); for(int i=0; i<n; i++) { a[0][i]=a[1][i]=i+1; printf("%d ",a[0][i]); } printf("\n");}int main() { int i,k,tmp; bool isEnd=true; char str[100]; printf("Please enter the number of n(n<10):\n"); scanf("%d",&n); init(); while(1) { init(); while(1) { isEnd=true; for(int j=n-1; j>=1; j--) { if(a[flag][j-1]<a[flag][j]) { i=j-1; isEnd=false; break; } } if(isEnd) break; a[flag][n]=0; for(int j=i+1; j<=n; j++) { if(a[flag][i]>a[flag][j]) { k=j-1; break; } } tmp=a[flag][i]; a[flag][i]=a[flag][k]; a[flag][k]=tmp; for(int j=0; j<=i; j++) { a[!flag][j]=a[flag][j]; } for(int j=i+1; j<n; j++) { a[!flag][j]=a[flag][n+i-j]; } flag=!flag; for(int j=0; j<n; j++) { printf("%d ",a[flag][j]); } printf("\n"); cnt++; } printf("The totol number: %d\n",cnt); printf("Continue?:y/n\n"); scanf("%s",str); if(str[0]=='Y' || str[0]=='y') { printf("Please enter the number of n(n<10):\n"); scanf("%d",&n); } else break; } return 0;}
0 0
- 全排列生成算法之字典序
- 字典序全排列生成算法
- 字典序法生成全排列算法
- 全排列字典序生成算法
- 全排列算法之字典序法
- 生成字典序全排列
- 全排列的生成算法 字典序法
- 字典序全排列生成算法提速[一次作业]
- 字典序法生成全排列算法的证明
- 字典序法生成全排列算法的证明
- 全排列的生成算法:字典序法
- 字典序法生成全排列算法的证明
- 全排列的生成算法:字典序法
- 字典序全排列算法
- 全排列算法的字典序排列
- 算法02:全排列字典序算法
- 字典序法生成全排列
- 字典序法生成全排列
- Dynamic programming
- 单链表的各操作实现
- GridLayout使用2
- 【JavaScript】多输入框的输入字数即时检查
- 初尝2D骨骼动画编辑工具SPINE
- 全排列生成算法之字典序
- 嵌入式C语言中printf函数的使用(二)——SWO引脚的巧妙应用
- poj 1287||zoj 1372 Networking 最小生成树 kruskal 克鲁斯卡尔算法
- JAVA2核心技术中的GBC类
- hdu1757---A Simple Math Problem(矩阵)
- IOS 调整内存中的图片大小
- HDU 5011-Game(尼姆博弈)
- CSDN-markdown编辑器简洁的语法与呈现效果对照2
- 编程好的规则