【问题标题】:for each in C++ fails to update the vector对于 C++ 中的每个都无法更新向量
【发布时间】:2018-07-21 20:05:28
【问题描述】:

我 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 循环,它给出了正确的解决方案。

【问题讨论】:

  • 也许把它变成一个minimal reproducible example 有一些输入、预期输出以及你的输出有何不同。
  • 对正在迭代的容器进行变异可能会有问题,因为某些类型的变异会使迭代器无效(这是不好的)。
  • 你确定这是你的真实代码吗? res.reserve(); 行无法编译。

标签: c++ for-loop foreach


【解决方案1】:

显示的代码表现出未定义的行为。

在for循环内部:

    res.push_back(temp);

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

for(auto t:res){

for 循环遍历向量。范围迭代在内部使用迭代器来迭代容器。只要这里的第一个push_back 向向量添加一个值,这个for-loop 的下一次迭代就是未定义的行为。游戏结束。

【讨论】:

    【解决方案2】:

    这里的问题是您正在循环到目前为止创建的子集,然后在同一个循环中添加更多子集,并附加它们。这有两个问题。

    • 首先(正如 Sam 所指出的),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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-07
      • 1970-01-01
      • 2023-04-11
      • 2021-10-18
      • 2019-10-06
      • 2015-08-16
      • 2010-12-23
      • 1970-01-01
      相关资源
      最近更新 更多