原文章地址:https://blog.csdn.net/a987073381/article/details/52016960
2018年6月22日
话不多说,这个题很可能出现在你笔试的编程题当中,因此还是有必要做一做的。
刚开始碰到这个问题,准备用穷尽法进行作答,但是发现自己并不知道怎么怎么进行穷举,利用位操作很好的了这个问题。
比方10 个数 我们可以穷举100000 00000 ~1 11111 11111,这样一个11位来进行,一个数组{-10, 6, 9, 10, 17, 18, 20, 35, 45, 99},对应其中的某位,0表示选中,1表示没选中,因为要选出里面的m个数来使得 和为sum,所以是穷举所有的这个11位 中有6位的情况(因为第一个占一个1),
int NumOf1(int num) //统计其中的1的个数
{
int count = 0;
while (num)
{
num = num & (num - 1);
count++;
}
return count;
}
void CalSum(vector<int> &nums, int result, int m)
{
int len = nums.size();
int bit = 1 << len;
for (int i = 1; i < bit; i++) //从1循环到2^N
{
int sum = 0;
vector<int> tmp;
if (NumOf1(i) == m)
{
for (int j = 0; j < len; j++)
{
if ((i & 1 << j) != 0) //用i与2^j进行位与运算,若结果不为0,则表示第j位不为0,从数组中取出第j个数
{
sum += nums[j];
tmp.push_back(nums[j]);
}
}
if (sum == result)
{
for (vector<int>::iterator iter = tmp.begin(); iter != tmp.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
}
}
}