问题:
求一个集合的所有子集
讨论:
暴力情况下2n幂指数的复杂度,2n个子集。发现其中的规律:某一个元素存在与否可以作为选择子集的基本方法,元素存在和不存在为两者情况。值得注意的是,重复元素怎么办?先保留这个问题,从一般再到特殊。因此思路就出来了:对集合中的元素从头开始遍历,选该元素,进到子集集合中,不选该元素,开始考虑后一元素。为提高效率,选择Vector的 emplace_back更新子集,。
emplace_back与push_back
两者都是添加对象到vector,有什么区别呢?
首先emplace_back添加到vector中,可以自动调用构造函数进行初始化,而push_back先将对象传递给push_back,再将这些对象拷贝到vector中,因此需要显示调用类来进行构造;另一方面,调用emplace_back不用进行内存移动。类似的于insert,push_front对应的C++11函数为emplace,emplace_front
回到题目:
当考虑某个元素nums[i]时,不使用他,则直接跳过,遍历下一个;用它subset.emplace_back(nums[i),再遍历下一个。
Code:
#include<iostream>
#include<vector>
using namespace std;
void subset(vector<int> nums,vector<int>& subs,int i){
if(nums.empty())
{
return ;
}
if (i == nums.size())
{
cout<< "[" <<" ";
for (auto e : subs)
{
cout<<e<<" ";
}
cout<<" ]";
}
else
{
subset(nums,subs,i+1);//直接不予考虑nums[i]
subs.emplace_back(nums[i]);//考虑nums[i]
subset(nums,subs,i+1);//考虑nums[i]后,再遍历后面的元素
}
}
int main(){
vector<int> nums= {1,2,3,4};
subset(nums,{},0);
return 0;
}