如何从stl向量中删除具有特定值的项目?

时间:2020-03-05 18:46:33  来源:igfitidea点击:

我查看了stl vector的API文档,并注意到vector类上没有允许删除具有特定值的元素的方法。这似乎是一种常见的操作,而且似乎没有内置的方法可以执行此操作,这很奇怪。

解决方案

回答

使用带有begin和end迭代器的全局方法std :: remove,然后使用std :: vector.erase实际删除元素。

文档链接
std :: remove http://www.cppreference.com/cppalgorithm/remove.html
std :: vector.erase http://www.cppreference.com/cppvector/erase.html

std::vector<int> v;
v.push_back(1);
v.push_back(2);

//Vector should contain the elements 1, 2

//Find new end iterator
std::vector<int>::iterator newEnd = std::remove(v.begin(), v.end(), 1);

//Erase the "removed" elements.
v.erase(newEnd, v.end());

//Vector should now only contain 2

感谢Jim Buck指出我的错误。

回答

另请参阅std :: remove_if以能够使用谓词...

这是上面链接中的示例:

vector<int> V;
V.push_back(1);
V.push_back(4);
V.push_back(2);
V.push_back(8);
V.push_back(5);
V.push_back(7);

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
    // The output is "1 4 2 8 5 7"

vector<int>::iterator new_end = 
    remove_if(V.begin(), V.end(), 
              compose1(bind2nd(equal_to<int>(), 0),
                       bind2nd(modulus<int>(), 2)));
V.erase(new_end, V.end()); [1]

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
    // The output is "1 5 7".

回答

std :: remove实际上并没有从容器中删除该元素,但确实返回了新的结束迭代器,该迭代器可以传递给container_type :: erase以真正去除容器中现在存在的多余元素:

std::vector<int> vec;
// .. put in some values ..
int int_to_remove = n;
vec.erase(std::remove(vec.begin(), vec.end(), int_to_remove), vec.end());

回答

如果我们有未排序的向量,则可以简单地与最后一个向量元素交换,然后是resize()

使用有序的容器,最好使用?std :: vector :: erase()。注意,在<algorithm>中定义了一个std :: remove(),但是实际上并没有进行擦除。 (请仔细阅读文档)。

回答

其他答案涵盖了如何做到这一点,但我想我也要指出,向量API中没有这个并不是很奇怪:在向量中线性搜索无效的值,然后是一堆复制将其删除。

如果我们正在密集地执行此操作,则出于这个原因,值得考虑使用std :: set。