vector erase() 函数可以删除两个连续的相同元素吗?
Can vector erase() function delete two consecutive same elements?
下面是我的程序片段。我遍历一个向量并尝试删除所有具有
三的价值。但是我把vector的内容打印出来之后,是1-2-4-3-5,还是有数字3,为什么呢?如果要删除两个连续的相同元素,是否需要专门处理iterator?
int main()
{
std::vector<int> a = {1, 2, 3, 4, 3, 3, 5}; // a has size 5
for(auto it=a.begin();it!=a.end();)
{
if(*it == 3) it=a.erase(it);
it++;
}
for(auto x:a) cout<<x<<endl;
}
我们可以分解你的例子,只看最后三个数字 3, 3, 5
。
擦除第一个 3 后,在
中返回第二个 3 的迭代器
it = a.erase(it);
但紧接着 it
递增
it++;
现在指向 5。
这里可以使用erase-remove-idiom。示例代码:
a.erase(std::remove(a.begin(), a.end(), 3), a.end());
<algorithm>
中有一个名为 remove_if(first, last, func)
的方法可以解决您的问题。它更安全。请检查以下代码片段 -
#include <iostream>
#include <vector>
#include <algorithm>
bool isThree(int k){
return (k == 3);
}
int main(){
std::vector<int> v {1,2,3,4,5,6,7,3,3,3};
std::vector<int>::iterator it;
v.erase(std::remove_if(v.begin(), v.end(), isThree), v.end());
for(int i=0;i<v.size(); i++){
std::cout << v[i] << " ";
}
return 0;
}
这个错误是你在删除一个元素时跳过检查一个元素。这是因为 it = a.erase(it);
将所有元素向后移动到 it
和 returns it
- 要解决此问题,请在擦除时不要增加 it
:
for(auto it=a.begin();it!=a.end();)
{
if(*x == 3) it=a.erase(it); else it++;
}
此代码也很慢,因为它可能是 o(n^2)
操作 - 您最好使用 std::remove
然后触发 erase/resize 以使您的矢量大小正确。
下面是我的程序片段。我遍历一个向量并尝试删除所有具有 三的价值。但是我把vector的内容打印出来之后,是1-2-4-3-5,还是有数字3,为什么呢?如果要删除两个连续的相同元素,是否需要专门处理iterator?
int main()
{
std::vector<int> a = {1, 2, 3, 4, 3, 3, 5}; // a has size 5
for(auto it=a.begin();it!=a.end();)
{
if(*it == 3) it=a.erase(it);
it++;
}
for(auto x:a) cout<<x<<endl;
}
我们可以分解你的例子,只看最后三个数字 3, 3, 5
。
擦除第一个 3 后,在
中返回第二个 3 的迭代器it = a.erase(it);
但紧接着 it
递增
it++;
现在指向 5。
这里可以使用erase-remove-idiom。示例代码:
a.erase(std::remove(a.begin(), a.end(), 3), a.end());
<algorithm>
中有一个名为 remove_if(first, last, func)
的方法可以解决您的问题。它更安全。请检查以下代码片段 -
#include <iostream>
#include <vector>
#include <algorithm>
bool isThree(int k){
return (k == 3);
}
int main(){
std::vector<int> v {1,2,3,4,5,6,7,3,3,3};
std::vector<int>::iterator it;
v.erase(std::remove_if(v.begin(), v.end(), isThree), v.end());
for(int i=0;i<v.size(); i++){
std::cout << v[i] << " ";
}
return 0;
}
这个错误是你在删除一个元素时跳过检查一个元素。这是因为 it = a.erase(it);
将所有元素向后移动到 it
和 returns it
- 要解决此问题,请在擦除时不要增加 it
:
for(auto it=a.begin();it!=a.end();)
{
if(*x == 3) it=a.erase(it); else it++;
}
此代码也很慢,因为它可能是 o(n^2)
操作 - 您最好使用 std::remove
然后触发 erase/resize 以使您的矢量大小正确。