对于每个在C ++中无法更新向量

时间:2018-07-21 20:05:29

标签: c++ for-loop foreach

我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循环,它将提供正确的解决方案。

2 个答案:

答案 0 :(得分:3)

显示的代码表现出不确定的行为。

在for循环内:

    res.push_back(temp);

std::vector中添加新元素会使矢量的所有现有迭代器无效(关于此主题,存在几种边缘情况,但此处与它们无关)。但是,这是在for循环内部:

for(auto t:res){

for循环遍历向量。在内部,范围迭代使用迭代器对容器进行迭代。一旦第一个push_back在向量中添加了一个值,此for循环的下一次迭代就是未定义的行为。游戏结束。

答案 1 :(得分:0)

这里的问题是,您要遍历到目前为止已创建的子集,然后在同一循环中添加更多子集,并将其追加。这有两个问题。

  • 首先(由Sam指出),vector::push_back()可能会使控制循环的迭代器无效,从而破坏代码。
  • 第二,即使使用容器(例如dequelist)(其中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;
}