1. 程式人生 > >C++排列組合(從N個數中選擇M個數的所有情況)

C++排列組合(從N個數中選擇M個數的所有情況)

 待選擇的數存放在in矩陣中,矩陣的大小為N,從中選出target=M個數,給出所有可能情況。

思路:

in矩陣存放的數為(M=2,N=4):

下標 0 1 2 3
元素 1 2 3

4

 定義一個數i,從0~2^N,其二進位制位數N位,分別表示是否選擇第N位,

一個都不選 0000 選擇下標為0的 1000
選擇下標為3的 0001 選擇下標為0,3的 1001
選擇下標為2的 0010 選擇下標為0,2的 1010
選擇下標為2,3的 0011 選擇下標為0,2,3的 1011
選擇下標為1的 0100 選擇下標為0,1的 1100
選擇下標為1,3的 0101 選擇下標為0,1,3的 1101
選擇下標為1,2的 0110 選擇下標為0,1,2的 1110
選擇下標為1,2,3的 0111 選擇下標為0,1,2,3的 1111

可以看出二進位制為1的位數之和等於M的是我們需要的組合

所以接下來遍歷0~2^N的數,找出其中二進位制為1的位數之和等於M的數,並根據1在二進位制中的位置轉換為in的下標,得到輸出矩陣output,其中每個元素都是組合的一種情況。

程式碼如下:

#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<vector <int>> zuhe(vector<int> in,int target){//target 是希望選擇M個作組合,in是選擇的範圍,長度為N
	vector<vector <int>> output;
	for(int i=0;i<pow(2,in.size());i++){
		int temp=0, count=0;
		vector<int> weishu;
		for(int j=0;j<in.size();j++){
			if((i&(1<<j))!=0){
				weishu.push_back(j);count++;}//找出二進位制為1的位數以及它們的位置
		}
		if(count==target){//位數等於M
		vector<int> one_case;
		for(int j=0;j<count;j++){
			temp = in.size() -1-weishu[j];
			one_case.push_back(in[temp]);
		}
		output.push_back(one_case);
		} 
	}
	return output;
}
int main()
{
	vector<vector <int>> output;
	vector<int> in={1,2,3,4};
	output = zuhe(in, 2);
	for(auto i:output){
		for(auto j:i) cout<<j<<' ';
		cout<<endl;
	}
	return 0;
}