全排列生成算法
来源:互联网 发布:以太坊 挖矿 windows 编辑:程序博客网 时间:2024/04/28 08:35
全排列生成算法
概述
全排列问题,简单来说,就是由n个不同元素组成的序列,从中取出n个元素,按不同顺序排列起来。如:”123”,它的全排列为,”123”,”132”,”213”,”231”,”312”,”321”,总共有n!种结果。
解法一:回溯法求解
对于求解所有可能情况的问题,回溯法不失为一种可以解决问题的方法。对于全排列生成,可以把序列的每一个字符作为一层,也可以说是,固定一个字符,对剩余的其他字符求解全排列,举个例子:
“123”
固定1,求解”23”的全排列,与1组合,则是以1开头的,所有可能的排列;
固定2,求解”13”的全排列,与2组合,则是以2开头的,所有可能的排列;
固定3,求解”12”的全排列,与3组合,则是以3开头的,所有可能的排列。
当序列仅有一个元素时,全排列只有一种,是它本身。回溯法求全排列的过程,求解完固定一个字符的全排列之后,回溯到上层,再固定另一个求解的过程。
具体代码如下:
void cal_all_permutation(char *perm, int from, int to){ if (to <= 1) { return; } if (from == to) { int i; for (i = 0; i <= to; ++i) { printf("%c", perm[i]); } printf("\n"); } else { int i; for (i = from; i <= to; ++i) { std::swap(perm[i], perm[from]); cal_all_permutation(perm, from + 1, to); std::swap(perm[i], perm[from]); //回溯过程 } }}
解法二:字典序排序
字典序排序算是解决全排列生成问题的一种很好的方法,根据字符串各元素的字典序,可以确定两个字符串的大小关系。
这里要先确定两个前提:
- 字符串初始状态必须经过升序排序;
- 字符串初始状态是最小的一种排列。
对于1,字典序排序解决全排列问题,核心思想是,在求解下一个排列时,下一个排列恰好比当前排列大,并且所求的下一个排列是比当前排列大的所有排列中最小的,当前序列变为降序排序之后,就没有比其更大的排列了,全排列所有情况求解得到。
对于2,字典序确定两个字符串大小时,是一次比较各个相应位置上的元素的大小,对于位置i, p1[i] > p2[i]则p1大于p2,同理,p1[i] < p2[i]则p1小于p2,仅有两者字符完全相同的情况下才相等。因此,当初始状态时,升序排序之后,任意字符串与其比较时,对于每个位置,并不可能再找出一个比初始状态的该位置元素更小的元素(注意,排列问题中,各元素是不能重复的)。所以初始状态必定为最小排列。以下则是字典序排序具体描述:
字典序排序算法描述:
1. 从序列sz - 2位置开始(序列索引从0开始,末尾元素索引为sz - 1),寻找第1个使得perm[i] < perm[i + 1]成立的元素,并记录索引i;2. 从序列sz - 1位置开始,在字典序大于perm[i]的元素中,寻找最小的那个元素,并记录索引j;3. 交换perm[i]与perm[j];4. 反转perm[i]至perm[sz - 1]之间的子序列,即i + 1 -> sz - 1。
bool cal_next_permutation(char *perm, int sz){ int i; //寻找第1个使得perm[i] < perm[i + 1]成立的元素 for (i = sz - 2; (i >= 0) && (perm[i] >= perm[i + 1]); --i) { ; } //未找到,说明当前排列为降序排序,不可能有更大的排列了 if (i < 0) { return false; } int j; //寻找大于第一步中找到的元素的最小值 for (j = sz - 1; (j > i) && (perm[j] <= perm[i]); --j) { ; } std::swap(perm[i], perm[j]); reverse(perm + i + 1, perm + sz); return true;}
- 全排列生成算法
- 全排列生成算法 .
- 全排列生成算法
- 全排列生成算法
- 全排列生成算法
- 全排列生成算法
- 全排列生成算法
- 全排列生成算法
- 全排列生成算法
- 有序全排列生成算法
- 全排列的生成算法
- 全排列的生成算法
- 全排列的生成算法
- 全排列的生成算法
- 全排列生成算法小结
- 全排列的生成算法
- 有序全排列生成算法
- 全排列的生成算法
- Android中常见的内存泄漏
- iOS App中第一次运行添加半透明新手指引
- 查看 创建表的sql
- 函数调用时的参数传递和栈帧结构问题
- Struts遍历标签s:iterator总结
- 全排列生成算法
- MySQL在没有可视化界面下查看数据库内容
- 第九篇:亚盘的平衡手法
- 类似朋友圈,评论View
- 抓包工具Fiddler的使用教程(三):如何模拟弱网环境
- Android 自定义橡皮擦效果
- 设置APACHE支持SSL
- 合理使用JTAG和IMPACT帮助你调试FPGA不能启动的问题
- gitHub 的使用