要从std::vector
中删除迭代器,我可以做以下两件事:
std::vector<int>& vec = myNumbers; // use shorter name
vec.erase(std::remove(vec.begin(), vec.end(), number_in), vec.end());
或者我可以这样做:
auto it = find(vec.begin(), vec.end(), number_in);
vec.erase(it);
第二种更直观,我猜,但哪一种更快?
修改: 向量中的元素是唯一的,我们不必担心一次删除多个元素。
答案 0 :(得分:2)
第一个版本保证正常工作,而第二个版本可能更快(由于std::find
停在匹配的第一个项目上),但肯定不是更安全。
auto it = find(vec.begin(), vec.end(), number_in);
if (it != vec.end())
vec.erase(it);
这样可以确保您没有删除无效的迭代器。
所以这取决于你的需求。如果你想要一个正确的程序,第一个程序可以在没有进一步干预的情况下工作,但是第二个程序需要来自客户的错误罚单,然后你必须修复它(如上所述)。
答案 1 :(得分:1)
第二个更快 - 第一个会尝试找到等于number_in
的所有元素,尽管它已经找到了一个。{但是,第二个会在找到它时停止。
答案 2 :(得分:1)
std :: vector :: erase
删除pos处的元素。
删除范围内的元素[first;最后一个)。
在擦除点或之后使迭代器和引用无效,包括end()迭代器。 迭代器pos必须是有效且可解除引用的。因此,end()迭代器(有效但不可解除引用)不能用作 pos的值。 如果first == last,迭代器首先不需要可解除引用:删除空范围是无操作。
http://en.cppreference.com/w/cpp/container/vector/erase
第一种方法会慢一些,因为将搜索整个向量的数字。但它也是更安全的方式。考虑number_in
不是向量的元素。第一种方法是尝试擦除定义且安全的空范围。第二种方法是尝试擦除不安全和UB的矢量的结束迭代器。
答案 3 :(得分:1)
您似乎对效果感兴趣。找到(第一个)匹配元素不能比O(n)
更快地完成。因此,您可以尝试提高性能的部分是删除,可以是O(1)
,如果允许
要更改的向量元素的顺序。例如
// find requires up to O(n)
auto it = std::find(v.begin(),v.end(),value);
// remove in O(1) but don't preserve order
if(it!=v.end()) {
std::iter_swap(it,--(v.end()));
v.pop_back();
}
请注意,使用std::remove()
和/或vector::erase()
的解决方案将保留其余元素的顺序,因此不可避免的仍会压缩其余元素(引自Tony D的评论) ),这几乎总是比找到匹配元素更昂贵,因此支配计算成本。
试试哪种解决方案更快 - 布丁的证据就在吃!