【问题标题】:Why does my vector not re-size properly after erasing items?为什么我的矢量在擦除项目后无法正确调整大小?
【发布时间】:2021-08-20 20:52:14
【问题描述】:

我编写了一个小程序来从向量中删除 0。但是当我检查时,向量中仍然有一个零。为什么?

大小应该是 3 时显示为 4,但仍然显示为零。

int main()
{

    vector<int> nums1 = {1, 2, 3, 0, 0, 0};

    for(int i=0; i< nums1.size(); i++)
    {
        if(nums1[i] == 0)
            nums1.erase(nums1.begin() + i);
    }
    cout << "size is now: " << nums1.size() << endl;

    for(int j=0; j<nums1.size(); j++)
        cout<< nums1[j] << endl;
    return 0;
}

【问题讨论】:

标签: c++ vector erase


【解决方案1】:

当向量的一个元素被擦除时,所有跟随它的元素都会向左移动,占据被擦除元素的位置。

也就是说,如果i 位置的元素被删除,那么它后面的元素现在将位于该位置。所以你不应该增加职位。

例如

for(  std::vector<int>::size_type i=0; i < nums1.size(); )
{
    if(nums1[i] == 0)
        nums1.erase(nums1.begin() + i);
    else
        ++i;
}

注意在 C++ 20 标准之前你可以使用标准算法 std::remove like

nums1.erase( std::remove( nums1.begin(), nums1.end(), 0 ), nums1.end() );

【讨论】:

  • 你写的第二个函数很棒。我是使用向量的新手,所以谢谢你的解释。
【解决方案2】:

正如评论中提到的,当你擦除时,你的向量被修改了,所以你不能以同样的方式增加你的迭代器。

更惯用的方式是:

for(auto i=nums1.begin(); i != nums1.end(); )
{
    if(*i == 0)
        i = nums1.erase(i); // when erased, move to element after erased one
    else
        i++; // otherwise, increment
}

【讨论】:

  • 解释一下。我的增量不正确。非常感谢。
【解决方案3】:

还值得一提的是,如果您使用的是 C++20,标准库已经改进了对此的支持,它更加干净、简洁且不易出错:

#include <vector>
#include <algorithm>

int main() {
    std::vector v{1, 2, 0, 0, 0, 5};
    std::erase(v, 0);
}

离开v控股:{1, 2, 5}

【讨论】:

  • 谢谢你。我目前正在使用 c++11 进行编译。我将更新我的 ide 以使用 c++20 进行编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-01
  • 2018-04-07
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 2015-09-23
相关资源
最近更新 更多