c++ - 基于 C++ 范围的 for 循环和元素副本
问题描述
我想生成给定向量的所有子集:
vector<vector<int>> findSubsets(const vector<int> &nums) {
vector<vector<int>> subsets;
subsets.push_back(vector<int>{}); //empty set
for (auto current_num : nums)
{
//add current_num to all existing subsets
int n = subsets.size();
for (int i = 0; i < n; i++) {
vector<int> set(subsets[i]);
set.push_back(num);
subsets.push_back(set);
}
}
return subsets;
}
我想使用基于范围的 for 循环来迭代所有子集,它会给出不同的结果:
vector<vector<int>> findSubsets(const vector<int> &nums) {
vector<vector<int>> subsets;
subsets.push_back(vector<int>{}); //empty set
for (auto current_num : nums)
{
//add current_num to all existing subsets
for (vector<int> subset : subsets)
{
subset.push_back(current_num);
subsets.push_back(subset);
}
}
return subsets;
}
但这并没有达到我的预期。我错过了什么?
解决方案
正如@Fureeish 在评论中提到的,第二个版本的一个问题是在迭代子集向量时插入子集向量。
for (vector<int> subset : subsets)
{
subset.push_back(current_num);
subsets.push_back(subset); // Should not modify vector while iterating on it
}
range 语句扩展为:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
__end 表达式在迭代之前展开。对于向量,这可能是计算 vector.data[size] 处的地址。如果循环将新元素推入向量中,则 __end 表达式不再正确。
如果您改为遍历向量的副本,则 range 语句将起作用。例如:
for (vector<int> subset : vector<vector<int>>(subsets))
{
subset.push_back(current_num);
subsets.push_back(subset);
}
推荐阅读
- c++ - 以函数作为模板参数的 C++ 函数调用包装器对象
- swift - 不使用 Storyboard 时,使用 Swift 初始化 UIViewController 的正确方法是什么?
- node.js - 使用 pm2 watch 重建 Typescript 文件
- python - Numpy:如何在数组中找到最频繁的非零值?
- node.js - 如何确定嵌套文档是实际的子模式还是 Mongoose 中的对象
- sql - 如何按以下 sql 子查询分组
- python - 在数组 PYTHON 中查找连续整数对
- r - 如何在R中索引预测plm对象
- python - 如何使用 JDebug 为 bt 堆栈跟踪选项调用“bt”命令
- django - Heroku 不会在 Django 上收集静态数据,但告诉它确实如此