我for_each一个向量,并在for循环内更改了向量。但是,当我运行程序时,在程序离开for循环之后,向量仍然保持不变。是什么引起了问题?如果我仍然想使用for_each循环,该如何解决?
下面是代码(我对leetcode 78的解决方案):
class Solution {
public:
void print(vector<int> t){
for(int a:t){
cout<<a<<" ";
}
cout<<endl;
}
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
res.push_back(vector<int>{});
int m=nums.size();
for(int a:nums){
cout<<"processing "<<a<<endl;
for(auto t:res){
vector<int> temp{a};
temp.insert(temp.end(),t.begin(), t.end());
res.push_back(temp);
cout<<"temp is ";
print(temp);
res.reserve();
}
// int s=res.size();
// for(int i=0;i<s;i++){
// vector<int> temp{a};
// temp.insert(temp.end(), res[i].begin(), res[i].end());
// res.push_back(temp);
// }
}
return res;
}
};
如果我用注释掉的位置替换了for_each循环,它将提供正确的解决方案。
答案 0 :(得分:3)
显示的代码表现出不确定的行为。
在for循环内:
res.push_back(temp);
在std::vector
中添加新元素会使矢量的所有现有迭代器无效(关于此主题,存在几种边缘情况,但此处与它们无关)。但是,这是在for循环内部:
for(auto t:res){
for循环遍历向量。在内部,范围迭代使用迭代器对容器进行迭代。一旦第一个push_back
在向量中添加了一个值,此for
循环的下一次迭代就是未定义的行为。游戏结束。
答案 1 :(得分:0)
这里的问题是,您要遍历到目前为止已创建的子集,然后在同一循环中添加更多子集,并将其追加。这有两个问题。
vector::push_back()
可能会使控制循环的迭代器无效,从而破坏代码。deque
或list
)(其中push_back()
不会使任何指针无效),您的循环也将无限期地运行,因为您不断添加新的元素。 正确的方法是只循环在循环开始之前创建的子集,然后添加新的子集,即子集的数量加倍。实现此目的最简单的方法是使用良好的基于索引的旧循环,并在开始时分配/保留足够的子集(2 ^ n)。
vector<vector<int>> subsets(vector<int> const& nums)
{
const auto n=nums.size();
vector<vector<int>> subset(1<<n); // there are 2^n distinct subsets
for(size_t i=0,j=1; i!=n; ++i) // loop distinct nums
for(size_t k=j,s=0; s!=k; ++s) { // loop all subsets so far s=0..j-1
auto sset = subset[s]; // extract copy of subset
sset.push_back(nums[i]); // extend it by nums[i]
subset.at(j++) = move(sset); // store it at j
}
return subset;
}