为什么我的矢量在擦除项目后不能正确调整大小?

Why does my vector not re-size properly after erasing items?

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

尺码显示为 4,而应为 3,但仍显示为零。

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;
}

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

更惯用的方式是:

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
}

还值得一提的是,如果您使用的是 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}

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

也就是说,如果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() );