全排列的实现
来源:互联网 发布:mac磁盘名称 编辑:程序博客网 时间:2024/05/18 09:09
实现方法
文章主要讲两种实现全排列的方法:
1. 使用C++的STL模板实现数字或字符的全排列。
2. 使用递归的思想实现数字或字符的全排列。
STL模板实现
在C++的模板中,有一对专门用于实现数字或字符全排列的模板:next_permutation(_BIter, _BIter)和prev_permutation(_BIter, _BIter)。前者实现向后排列,后者实现向前排列,即前者在原顺序上依次产生较大的排列,后者则相反。
举个例子:假设需要产生以“354”为基础的全排列,使用next_permutation(_BIter, _BIter),则下一个排列为“435”,而使用prev_permutation(_BIter, _BIter),则下一个排列为“345”。
#include <bits/stdc++.h>using namespace std;int main(){ string ss("1234"); while(next_permutation(ss.begin(), ss.end())) cout << ss << endl; return 0; }
输出结果为:
12431324134214231432213421432314234124132431312431423214324134123421412341324213423143124321
从上面的结果中我们可以发现没有原始排列“1234”,这时因为该模板实现的是以原始排列为基础依次产生后序排列,所以并不会产生原始的排列,这里需要注意下!
如果我们把上述代码中的next_permutation(ss.begin(), ss.end())
换成prev_permutation(ss.begin(), ss.end())
会产生什么结果呢?
结果如下:
什么都没有,这又是为什么呢?这是因为prev_permutation(_BIter, _BIter)产生的是以“1234”为基础的更小的排列,但是“1234”已经是最小的排列了,那么自然就不会产生任何结果了。既然是这样那我们把原ss改为“4321”是不是就可以了呢,我们看一下运行结果:
43124231421341324123342134123241321431423124243124132341231421432134143214231342132412431234
果然实现了全排列。(还是要注意,结果中同样没有原排列“4321”)
从上面的例子中不难看出,如果给你一个无序的字符串或者数组,那么你首先需要对它进行排序,然后才能使用模板来求全排列。
比如:
#include <bits/stdc++.h>using namespace std;int main(){ int num[5] = {3,2,4,1,5}; sort(num, num + 5);//先排序 while(next_permutation(num, num + 5)) { for(int i = 0; i < 5; ++i) cout << num[i]; cout << endl; } return 0;}
递归实现
设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。
1.当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素。
2.当n>1时,Perm(R)可由(r1)+Perm(R1),(r2)+Perm(R2),…,(rn)+Perm(Rn)构成。
举例“123”:
1+Perm(2,3)→1+(2+Prem(3)) = 123
1+Perm(2,3)→1+(3+Perm(2)) = 132
2+Perm(1,3)→2+(1+Perm(3)) = 213
2+Perm(1,3)→2+(3+Perm(1)) = 231
3+Perm(2,1)→3+(2+Perm(1)) = 321
3+Perm(2,1)→3+(1+Perm(2)) = 312
实现代码如下:
#include <bits/stdc++.h>using namespace std;void permutation(int arry[], int low, int high){ if(low == high) { //当low==high时,此时arry就是其中一个排列,输出arry for(int i = 0; i <= low; ++i) cout << arry[i]; cout << endl; } else { for(int i = low; i <= high; ++i) //每个元素与第一个元素交换 { swap(arry[i], arry[low]); permutation(arry, low + 1, high); //递归调用 swap(arry[i], arry[low]);//最后,将元素交换回来,复原 } }}int main(){ int num[4] = {1,2,3,4}; permutation(num, 0, 3); return 0;}
运行结果:
123412431324134214321423213421432314234124312413321432413124314234123421423142134321431241324123
递归方法实现参考于:算法设计-全排列递归
- 全排列的实现
- 全排列的实现
- 全排列的实现
- 全排列的实现
- 全排列的实现
- 全排列的实现
- 全排列的实现
- 全排列的实现
- 全排列的实现
- 全排列的实现
- Java实现的全排列和排列
- Java实现的全排列和排列
- 全排列的简单实现
- 全排列的一种实现
- 全排列的递归实现
- 全排列的递归实现
- 可复用的全排列实现
- 全排列的递归实现
- JAXB
- i2c驱动从注册到probe被调用
- 安卓提示错误:Error:(1, 0) Your project path contains non-ASCII characters.
- ubuntu14.04安装cuda7.5 详细教程
- python-列表删除所有指定元素
- 全排列的实现
- java位运算
- 基于H5canvas刮刮乐界面
- 使用GreenDao创建数据库
- noi 已知gcd和lcm求最小和?
- Xcode8 主工程嵌套自工程-静态Framework
- 数据库和多维数据库的权限管理的技巧
- # RESTful登录(基于token鉴权)的设计实例
- Handler的学习