每日一小练——按字典顺序列出所有排列
来源:互联网 发布:确定性的终结 知乎 编辑:程序博客网 时间:2024/06/05 23:06
上得厅堂,下得厨房,写得代码,翻得围墙,欢迎来到睿不可挡的每日一小练!
题目:按字典顺序列出所有排列
内容:请写一个程序,用字典顺序列出n个元素的所有排列
这个问题有点小复杂,不是太好想,反正我是想了好久。
看到这个题目我先是想到的就是递归因为这个题目就是用指针对高位选择,然后将指针传给临近的低位再选择。
不过仔细研究原来没这么简单。以n=4举例当处理以1开头的排列时1234到1432,但是在排列2开头的时候不太好建立统一的递归关系。(没办法太统一的递归方法中将后面的数字选出来),所以将第一位分类数字经行单独处理,其实第一位数字的选择也是又规律可循的。
1234 1432
2134 2431
3124 3421
4123 4321
12345 15432
21345 25431
....
可以看出1和2换时2都在最后一位,2和3换时,3在倒数第二位。。。就是你换第i个数时,就在倒数第i-1位。
然后我们再来处理除第一位的排列即从i,1,2,3,4,..i-1,i+i,..n(假设第一位是i)到i,n,...i+1,i-1,...3,2,1。的排列
其实这里也是有规律的,就是先从后向前查找第一个顺序相邻的位置然后交换,然后对交换后面的排列逆序。(其实这就是分解了我们人类排序的步骤,只是人的智能比较快,我们感受不到)。
比如 21354 从后向前第一个顺序相邻是35交换53为21534然后对后面逆序21435就是21354的后面一个数了。
当数列中没有顺序相邻了,我们的排列就结束了。
如 4321,54321。
所以我们就可以按照这个规律来编写程序了。
#include <iostream>using namespace std;int set[1000];bool signal = false;int n;int _tmain(int argc, _TCHAR* argv[]){void changeFirst();cout << "请输入排列的集合的最大整数n:" << endl;cin >> n;for (int i = 0; i < n; i++){set[i] = i + 1;}cout << "该集合的所有排列为:" << endl;changeFirst();getchar();getchar();return 0;}void swap(int &a, int &b){int temp = a;a = b;b = temp;}void reverse(int index_Start, int index_End){int length = index_End - index_Start;for (int i = 0; i <= length / 2; i++)swap(set[i + index_Start], set[length - i + index_Start]);}void permutationSet(){for (int x = 0; x < n; x++)cout << set[x] << " ";cout << endl;signal = false;int i, j, k;for (i = n - 2; i>0; i--)if (set[i]<set[i + 1]){j = i + 1;signal = true;break;}if (signal == false)return;for (k = n - 1; k>0; k--)if (set[k]>set[i])break;swap(set[i], set[k]);reverse(j, n - 1);permutationSet();}void changeFirst(){int i = n - 1;while (i >= 0){permutationSet();swap(set[0], set[i]);reverse(1, n - 1);i--;}}
实验结果
欢迎大家加入每日一小练,嘿嘿!
每天练一练,日久见功夫,加油!
-End-
参考文献:《c语言名题精选百则》
- 每日一小练——按字典顺序列出所有排列
- 每日一小练——按字典顺序列出所有子集
- 列出所有排列(字典顺序)
- 每日一小练——列出所有子集
- 列出所有子集(字典顺序)
- 按字典顺序打印字符串的所有排列
- 字符串的全排列——按字典顺序
- 列出字符串的所有排列
- 旋转法列出所有排列
- 列出所有子集-----字典顺序 2013年1月14日
- 对输入的字符串按字典顺序输出所有的全排列,字符串可以由重复字符
- 列出所有排列(旋转法)
- 产生所有排列---字典顺序-----2013年1月23日
- 列出所有子集(格雷码顺序)
- 按递增顺序打印数字n所有排列
- 组合-字典序打印所有排列
- 按递增顺序列出所有分母为40,分子小于40的最简分数
- 排列算法——字典序法
- Java反射入门
- 赋值运算符、左值与右值
- Python字符编码详解
- 日本已不放心将日台间水道交由台湾防守
- 在一个页面上根据已有的坐标添加图片,该如何处理
- 每日一小练——按字典顺序列出所有排列
- 隐私策略_实时天气
- EJB3.0开发指南:依赖值对象
- 设计模式之访问者模式
- git学习网址
- hibernate之fetch
- 为何要原汁原味地学习微积分(Calculus)?
- UVA Tree Summing
- cocos2d-x触摸事件详细分析