矢量擦除功能不起作用(简单代码)

use*_*284 1 c++

有人可以解释一下为什么这段代码不会从向量中删除所有 1:

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

jal*_*alf 6

让我们试试看。

假设你有一个包含内容的向量[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
    }
}
Run Code Online (Sandbox Code Playgroud)

第二次迭代:向量现在包含,[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
    }
}
Run Code Online (Sandbox Code Playgroud)

第三次迭代:向量现在包含 [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);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后结果:

向量包含[1].

正如您可能从手动逐行评估代码中看到的那样,问题是i即使在删除元素后您也会增加。每次删除一个元素时,都会将所有剩余的元素移动到较低的索引,但同时,您会增加计数器,因此您查看的下一个索引会更高。因此,当您删除元素时i,先前为 index 的元素将i+1移动到 index i。但是在下一次迭代中,您不再查看 index i,而是查看i+1,因此您跳过一个元素而从未查看它。