有人可以解释为什么这个矢量擦除操作不能正常工作吗?

Can someone explain why this vector erase operation isn't working properly?

    vector<int> nums{1,2,3,0,0,0};
    
    for(int i = 0; i< nums.size(); i++){
        if(nums[i] == 0){
            nums.erase(nums.begin() + i);
        }
    }
    for(int i = 0; i< nums.size(); i++){
        cout << nums[i] << " ";
    }
    //I keep getting [1, 2, 3, 0]

我想从向量中删除零,这样我只剩下 1,2,3。但是,我使用的方法似乎在最后留下一个零。我已经有一段时间了,我玩过索引,但我似乎无法让它正常工作。非常感谢您的帮助。

vector erase 函数减小了向量的大小。最后一个零没有被擦除,因为您正在擦除同一个 vector,其大小在 for 循环中被检查。

每次从向量中删除时,以下元素的索引都会减少 1。您需要考虑到这一点:

for(int i = 0; i< nums.size(); i++){
        if(nums[i] == 0){
            nums.erase(nums.begin() + i);
            --i; // <-- HERE
        }
    }

这是一个O(n^2)操作。您可以在 O(n) 中这样做:

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

Erase-Remove 已经介绍过了,所以这里是另一个,但较差,X-Y Answer。值得一提,因为它展示了如何使用 erase 的 return 值。

使用迭代器。

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

for(auto it = nums.begin(); it != nums.end(); ){
    if(*it == 0){
        it = nums.erase(it); // erase returns an iterator to the next element
                             // effectively it++ with the added benefit of it
                             // not being invalidated by removal from the vector
    }
    else {
        it++; // not removed? now we need to increment
    }
}
for(const auto & val: nums){
    cout << val << " ";
}