矢量擦除功能不工作(简单的代码)



谁能解释一下为什么这个代码不能从向量上擦除所有的15:

for (int i = 0; i < numbers.size(); i++)
{
    if (numbers[i] == 1)
    {
        numbers.erase(numbers.begin() + i);
    }
}

让我们试一试。

假设你有一个内容为[1, 1, 1]的向量(所有的,为了简单)

第一次迭代:

for (int i = 0; i < numbers.size(); i++) <-- i == 0; numbers.size() == 3
{
    if (numbers[i] == 1) <-- true
    {
        numbers.erase(numbers.begin() + i); <-- erase is called on element #0
    }
}

第二个迭代:向量现在包含了[1, 1],因为我们移除了第0个元素。

for (int i = 0; i < numbers.size(); i++) <-- i == 1; numbers.size() == 2
{
    if (numbers[i] == 1) <-- true
    {
        numbers.erase(numbers.begin() + i); <-- erase is called on element #1
    }
}

第三个迭代:向量现在包含[1]

for (int i = 0; i < numbers.size(); i++) <-- i == 2; numbers.size() == 1; the loop condition is false, so we exit the loop
{
    if (numbers[i] == 1)
    {
        numbers.erase(numbers.begin() + i);
    }
}

最终结果:

向量包含[1]

正如您可能从手动逐行计算代码中看到的那样,问题是即使在删除元素之后也增加了i。每次你移除一个元素,你把所有剩下的元素移到下标,但同时,你增加计数器,所以你看到的下一个索引是高一个。因此,当您删除元素i时,先前索引为i+1的元素被移动到索引i。但是在下一次迭代中,您不再查看索引i,而是查看索引i+1,因此您跳过了一个元素,而没有查看它。

您的代码显示我& lt;numbers。size(),你增加I同时删除n[I](如果它是1)删除后,不应该增加i,因为新数字会进入i的当前位置。

如果数字[]= {0、1、2、3、1、4}>你得到数字[]= {0、2、3、4}

如果数字[]= {0、1、1、2、3、1、4}>你得到数字[]= {0 1 2 3 4} ,

。E删除后,跳过下一个数字只要加上i——;删除数字后[i]

for (int i = 0; i < numbers.size(); i++){ if (numbers[i] == 1){ numbers.erase(numbers.begin() + i); i--; } }这将给你正确的答案。

当vector对象的一个元素被删除时,该元素之后的所有元素都向左移动。例如,如果索引为0的元素被删除,那么向量的第一个实际元素的索引将等于9。在这种情况下,您不能增加索引。

有效的循环可以像

for ( int i = 0; i < numbers.size(); )
{
    if ( numbers[i] == 1 )
    {
        numbers.erase( numbers.begin() + i );
    }
    else
    {
        ++i;
    }
}

考虑到应用标头<algorithm>

中声明的标准算法std::remove更简单例如

#include <algorithm>
//...
numbers.erase( std::remove( numbers.begin(), numbers.end(), 1 ), numbers.end() );

下面是一个示范示例

#include <iostream>
#include <vector>
#include <algorithm>
int main() 
{
    std::vector<int> v = { 1, 1, 2, 1, 3, 1, 4, 1, 5 };
    for ( int x : v ) std::cout << x << ' ';
    std::cout << std::endl;
    v.erase( std::remove( v.begin(), v.end(), 1 ), v.end() );
    for ( int x : v ) std::cout << x << ' ';
    std::cout << std::endl;
    return 0;
}

输出为

1 1 2 1 3 1 4 1 5 
2 3 4 5

最新更新