全排列的STL实现

来源:互联网 发布:软件项目培训教材资料 编辑:程序博客网 时间:2024/05/16 15:36

全排列的STL实现

全排列在很多程序都有应用,是一个很常见的算法,常规的算法是一种递归的算法,这种算法的得到基于以下的分析思路。

     给定一个具有n个元素的集合(n>=1),要求输出这个集合中元素的所有可能的排列。例如,如果集合是{a,b,c},那么这个集合中元素的所有排列是{(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)},显然,给定n个元素共有n!种不同的排列,如果给定集合是{a,b,c,d},可以用下面给出的简单算法产生其所有排列,即,集合(a,b,c,d)的所有排列有下面的排列组成:

(1)以a开头后面跟着(b,c,d)的排列

(2)以b开头后面跟着(a,c,d)的排列

(3)以c开头后面跟着(a,b,d)的排列

(4)以d开头后面跟着(a,b,c)的排列

这显然是一种递归的思路,于是我们得到了以下的实现:

#include<iostream>#include <algorithm>using namespace std;void permutation(char* a, int k, int m){if(k == m){for(int i = 0; i <= m; i++){cout << a[i];}cout << endl;}else{for(int j = k; j <= m; j++){swap(a[j], a[k]);permutation(a, k+1, m);swap(a[j], a[k]);}}}int main(){char a[] = "abc";permutation(a, 0, 2);return 0;}

#include<iostream>#include<cstdio>#include<map>#include<cstring>#include<cmath>#include<vector>#include<algorithm>#include<set>#include<string>#include<queue>#include <stack>using namespace std;#pragma warning(disable : 4996)const int MAXN = 25;int n, m;int ans[MAXN];int num[MAXN];bool vis[MAXN];void dfs(int x, int cnt){if(cnt == n + 1){for(int i = 1; i <= n; i++){cout << ans[i] << " ";}cout << endl;return;}for(int i = 1; i <= m; i++){if(!vis[i]){vis[i] = true;ans[cnt] = num[i];dfs(i, cnt + 1);vis[i] = false;}}}int main(){while (cin >> m >> n){for(int i = 1; i <= m; i++){cin >> num[i];}memset(vis, false, sizeof(vis));dfs(1, 1);}return 0;}


有时候递归的效率使得我们不得不考虑除此之外的其他实现,很多把递归算法转换到非递归形式的算法是比较难的,这个时候我们不要忘记了标准模板库已经实现的那些算法,这让我们非常轻松。

STL有一个函数next_permutation(),它的作用是如果对于一个序列,存在按照字典排序后这个排列的下一个排列,那么就返回true且产生这个排列,否则返回false。注意,为了产生全排列,这个序列要是有序的,也就是说要调用一次sort。实现很简单,我们看一下代码:

#include<iostream>#include<algorithm>using namespace std;void permutation(char* str, int length){sort(str, str + length);do{for(int i = 0; i < length; i++){cout << str[i];}cout << endl;}while(next_permutation(str, str + length));}int main(){char str[] = "acb";permutation(str, 3);return 0;}


而且我们可以绝对放心STL的高效