繁体   English   中英

从std :: vector中删除迭代器

[英]Remove by iterator from std::vector

要从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);

我想,第二个更直观,但哪一个更快?

编辑:向量中的元素是唯一的,我们不必担心一次删除几个元素。

第一个版本保证正常工作,而你的第二个版本可能更快(由于std::find停止在匹配的第一个项目),但它肯定不是更安全。

auto it = find(vec.begin(), vec.end(), number_in);
if (it != vec.end())
   vec.erase(it);

这将确保您不会删除无效的迭代器。

所以这取决于你的需求。 如果你想要一个正确的程序,第一个程序可以在没有进一步干预的情况下工作,但是第二个需要来自客户的错误票,然后你必须去修复它(如上所述)。

第二个是更快 - 第一个将尝试找到所有等于number_in的元素,尽管它已经找到了一个。 但是,第二个会在找到一个时停止。

的std ::矢量::擦除

  • 移除pos处的元素。

  • 删除范围内的元素[first; 持续)。

    在擦除点或之后使迭代器和引用无效,包括end()迭代器。 迭代器pos必须是有效且可解除引用的。 因此,end()迭代器(有效但不可解除引用)不能用作pos的值。 如果first == last,迭代器首先不需要是可解除引用的:擦除空范围是无操作。

http://en.cppreference.com/w/cpp/container/vector/erase

第一种方法会更慢,因为将搜索整个向量的数字。 但它也是更安全的方式。 考虑number_in不是向量的元素。 第一种方法是尝试擦除定义且安全的空范围。 第二种方法会尝试擦除不安全和UB的向量的结束迭代器。

您似乎对性能感兴趣。 找到(第一个)匹配元素不能比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的评论),这几乎总是更昂贵而不是找到匹配元素,因此支配计算成本。

试试哪种解决方案更快 - 布丁的证据就在吃!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM