有人可以解释一下为什么这段代码不会从矢量中删除所有1:
for (int i = 0; i < numbers.size(); i++)
{
if (numbers[i] == 1)
{
numbers.erase(numbers.begin() + i);
}
}
答案 0 :(得分:4)
我们试一试。
假设你有一个内容为[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
,因此您跳过一个元素而不查看它。
答案 1 :(得分:2)
你的代码说 我&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} ,
即删除后,它会跳过下一个号码 只需添加i--;删除数字后[i]
for (int i = 0; i < numbers.size(); i++){
if (numbers[i] == 1){
numbers.erase(numbers.begin() + i);
i--;
}
}
这将给你正确的答案。
答案 2 :(得分:1)
当擦除向量的元素时,擦除元素之后的所有元素都向左移动。因此,例如,如果删除了索引为0的元素,那么向量的第一个实际元素将具有等于9的索引。在这种情况下,不得增加索引。
有效循环可能看起来像
for ( int i = 0; i < numbers.size(); )
{
if ( numbers[i] == 1 )
{
numbers.erase( numbers.begin() + i );
}
else
{
++i;
}
}
考虑到应用标题std::remove
中声明的标准算法<algorithm>
更简单
例如
#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