如何从一个具有特定值的stl向量中删除一个项目?
我正在查看stl向量的API文档,并注意到向量类中没有方法可以删除具有特定值的元素。 这似乎是一个普遍的操作,似乎有些奇怪,没有内置的方式来做到这一点。
std :: remove实际上并没有从容器中擦除元素,但是它确实返回了可以传递给container_type :: erase的新的结束迭代器来执行REAL删除现在在容器末尾的额外元素:
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());
如果你想删除一个项目,下面会更有效率。
std::vector<int> v; auto it = std::find(v.begin(), v.end(), 5); if(it != v.end()) v.erase(it);
或者如果订单对您无关紧要,您可以避免移动项目的开销:
std::vector<int> v; auto it = std::find(v.begin(), v.end(), 5); if (it != v.end()) { using std::swap; // swap the one to be removed with the last element // and remove the item at the end of the container // to prevent moving all items after '5' by one swap(*it, v.back()); v.pop_back(); }
使用开始和结束迭代器的全局方法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指出我的错误。
如果你有一个未sorting的向量,那么你可以简单地交换最后一个向量元素,然后resize()
。
有了一个有序的容器,你最好用std std::vector::erase()
。 请注意,在<algorithm>
定义了一个std::remove()
,但实际上并没有进行擦除操作。 (请仔细阅读文档)。
其他答案涵盖了如何做到这一点,但我想我还要指出,这不是在向量API中是不是很奇怪:它是低效的,线性search的价值向量,其次是一堆复制删除它。
如果你正在密集的做这个操作,可以考虑使用std :: set来代替。
另请参见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".
一个较短的解决scheme(不强制你重复向量名称4次)将使用Boost:
#include <boost/range/algorithm_ext/erase.hpp> // ... boost::remove_erase(vec, int_to_remove);