使用 DFS 枚举子集
Enumerate subsets with DFS
我想枚举给定数组的所有可能子集,总共应该是 2^N。在这里,我使用 sum 来表示所有子集,因为在这个例子中,总和是不同的。我使用一个名为 take 的辅助数组来标记当前项目是否被采用并执行 DFS。这是代码:
void dfs(vector<int>& res, vector<int>& nums, vector<bool>& taken, int sum, int pos) {
for (int i = pos; i < nums.size(); ++i) {
if (!taken[i]) {
taken[i] = true;
res.push_back(nums[i] + sum);
dfs(res, nums, taken, sum + nums[i], pos + 1);
taken[i] = false;
}
}
return;
}
int main() {
vector<int> test = {1, 10, 100, 1000};
vector<bool> t(4, false);
vector<int> res;
dfs(res, test, t, 0, 0);
return 0;
}
但是此代码不会返回 2^n 结果。
我已经修复了你的代码
void dfs(vector<int>& res, vector<int>& nums, int sum, int pos) {
for (int i = pos; i < nums.size(); ++i) {
res.push_back(sum + nums[i]);
dfs(res, nums, sum + nums[i], i + 1); // i + 1 instead of pos + 1
}
return;
}
int main() {
vector<int> test = {1, 2, 3};
vector<int> res;
dfs(res,test,0, 0);
cout << res.size() << endl;
copy(res.begin(), res.end(), ostream_iterator<int>(cout , " "));
cout <<endl;
return 0;
}
而且由于您不会向后访问元素(即已经添加的索引),因此您不必维护一个数组来检查是否访问过。
void enumerate_all_subsets(vector <int> &res, const vector <int> &nums) {
if(nums.empty()) return;
for(auto i = 0ull; i < (1 << nums.size()); ++ i) {
int sum = 0;
for(auto k = 0; k < nums.size(); ++ k)
if((i >> k) & 1)
sum += nums[k];
res.push_back(sum);
}
}
这将迭代大小最大为 63 的向量(如果您的无符号长整型为 64 位)。任何更大的向量可能都应该重新考虑,因为这需要一段时间,因为这O(2^n)
,正如你所指出的。
基本上,unsigned long long i
的每个位代表一个nums
的位置,以及是否应该将其添加到总和中。
相关文章:
- 不带大括号的枚举形式
- 枚举环境变量的惯用C++14/C++17方法
- 类似枚举的计算常量
- 如何正确实现和访问运算符的各种自定义枚举器
- 错误:从"int"到枚举c++的转换无效
- C++中构造函数中的枚举
- 访问在 C++ 结构中声明的枚举变量
- 枚举类'classname'的多重定义
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- typedef 枚举和枚举类有什么区别?
- 为什么我的开关/机箱在使用枚举时默认?
- 标准::可选枚举的比较运算符
- C++两个源文件之间共享的枚举的静态实例
- 打印没有铸件的枚举可以在C++中吗?
- 枚举成员与静态 int 成员?
- C++:枚举:错误:应使用标识符而不是"}"
- 带有 c++ 的枚举(输入检查)
- C/C :提取一个枚举的子集以形成新的枚举
- 使用 DFS 枚举子集
- 只允许枚举的子集作为返回值 - 或 如何让编译器提醒我?在C++