各种排列组合的代码
一.产生类循环排列
输入样例
3 2
输出样例
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
输入样例
3 2
输出样例
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
#include <iostream> #include <ctime> using namespace std ; int A[100] ; void Print_permutation(int n, int *A , int cur) { int i , j ; if (cur == n) { /*for (i = 0 ; i < n ; ++ i) { cout << A[i] << " " ; } cout << endl ; */ } else { for (i = 1 ; i <= n ; i ++) { bool flag = true ; for (j = 0 ; j < cur ; ++ j) { if (A[j] == i) { flag = false ; break ; } } if (flag) { A[cur] = i ; Print_permutation(n,A,cur+1) ; } } } } int main() { int n = 0 ; clock_t start , end ; cin >> n ; start = clock() ; Print_permutation(n,A,0) ; end = clock() ; cout << endl << (double)(end-start)/CLOCKS_PER_SEC << "s" << endl ; return 0 ; } 实际上,这样的方法是用递归实现多重循环,本递归程序相当于n 重循环,每
重循环的长度为m 的情况,所以输出共有m^n 行。
二.不重复排列:
输入n 个数,输出由这n 个数构成的排列,不允许出现重复的项。
输入样例
3
1 1 2
输出样例
1 1 2
1 2 1
2 1 1
Version One :
LRJ代码:
#include <iostream> using namespace std ; int P[100] , A[100] ; void Print_permutation(int n , int *P , int *A , int cur) { if (cur == n) { for (int i = 0 ; i < n ; ++ i) { cout << A[i] << " " ; } cout << endl ; } else { for (int i = 0 ; i < n ; ++ i) { if (!i || P[i] != P[i-1]) { int c1 = 0 , c2 = 0 ; for (int j = 0 ; j < cur ; ++ j) { if (A[j] == P[i]) { c1 ++ ; } } for (int j = 0 ; j < n ; ++ j) { if (P[i] == P[j]) { c2 ++ ; } } if (c1 < c2) { A[cur] = P[i] ; Print_permutation(n,P,A,cur+1) ; } } } } } int main() { int n ; cin >> n ; for (int i = 0 ; i < n ; ++ i) { cin >> P[i] ; } Print_permutation(n,P,A,0) ; return 0 ; }
Version Two :
#include <iostream> using namespace std ; const int MAXN = 100 ; int A[MAXN] , P[MAXN] , used[MAXN] , tmp[MAXN] ; void Print_permutation(int n , int m , int *A , int *P , int cur) { if (cur == n) { for (int i = 0 ; i < n ; ++ i) { cout << A[i] << " " ; } cout << endl ; } else { for (int i = 0 ; i < m ; ++ i) { if (used[i] > -1) { used[i] -- ; A[cur] = P[i] ; Print_permutation(n,m,A,P,cur+1) ; used[i] ++ ; } } } } int main() { int n , m ; cin >> n ; int count = 0 ; memset(P,0,sizeof(P)) ; for (int i = 0 ; i < n ; ++ i) { cin >> tmp[i] ; P[count++] = tmp[i] ; for (int j = 0 ; j < i ; ++ j) { if (tmp[j] == tmp[i]) { used[j] ++ ; count -- ; break ; } } } for (int i = 0 ; i < count ; ++ i) { cout << P[i] << " " ; } cout << endl ; Print_permutation(n,count,A,P,0) ; return 0 ; }
(STL 中 next_permutation 方法实现核心)
template<class _BidIt> inline
bool next_permutation(_BidIt _First, _BidIt _Last)
{ // permute and test for pure ascending, using operator<
_DEBUG_RANGE(_First, _Last);
return (_Next_permutation(_Unchecked(_First), _Unchecked(_Last)));
}
template<class _BidIt> inline bool _Next_permutation(_BidIt _First, _BidIt _Last) { // permute and test for pure ascending, using operator< _BidIt _Next = _Last; if (_First == _Last || _First == --_Next) return (false); for (; ; ) { // find rightmost element smaller than successor _BidIt _Next1 = _Next; if (_DEBUG_LT(*--_Next, *_Next1)) { // swap with rightmost element that's smaller, flip suffix _BidIt _Mid = _Last; for (; !_DEBUG_LT(*_Next, *--_Mid); ) ; _STD iter_swap(_Next, _Mid); _STD reverse(_Next1, _Last); return (true); } if (_Next == _First) { // pure descending, flip all _STD reverse(_First, _Last); return (false); } } }
三.全排列:(没有重复元素的输入)
#include <iostream> using namespace std ; const int MAXN = 100 ; int used[MAXN] , A[MAXN] , P[MAXN] ; void Print_permutation(int n , int *A , int *P , int cur) { if (cur == n) { for (int i = 0 ; i < n ; ++ i) { cout << A[i] << " " ; } cout << endl ; } else { for (int i = 0 ; i < n ; ++ i) { if (!used[i]) { used[i] = 1 ; A[cur] = P[i] ; Print_permutation(n,A,P,cur+1) ; used[i] = 0 ; } } } } int main() { int n = 0 ; cin >> n ; for (int i = 0 ; i < n ; ++ i) { cin >> P[i] ; } memset(used,0,sizeof(used)) ; Print_permutation(n,A,P,0) ; return 0 ; }