待选择的数存放在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;
}