各种排列组合的代码

一.产生类循环排列
输入样例
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 ; 
} 

Version Three:
(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 ; 
} 
 
 

 

 

转载于:https://www.cnblogs.com/diyingyun/archive/2011/09/17/2179360.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值