通过迭代器从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::vector::erase
移除位置的元件
删除范围[first;last]中的元素。
使擦除点处或之后的迭代器和引用无效,包括end()迭代器。迭代器位置必须有效且可取消引用。因此,end()迭代器(有效,但不可取消引用)不能用作pos的值。如果first==last,则迭代器first不需要是可取消引用的:擦除空范围是不可行的。
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的评论),这几乎总是比找到匹配元素更昂贵,因此主导了计算成本。
试试哪种解决方案更快——布丁的证据就在吃!
- 删除C++中带有 vector<const char *> 的类
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 为什么通过 vector<reference_wrapper> 的元素删除引用的值<T>不会使向量无效?
- C++从 std::vector<std::function<中删除 std::function>>
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 从 std::vector 中删除项目时"Iterator not incrementable"
- 如何在不使用 vector::erase() 的情况下编写自定义 Vector 方法来删除元素?
- 在Visual Studio中删除成员std::vector::d ata()
- 在迭代 std::vector 时删除(间接)
- 删除[]是否可以与通用数组正常使用?如果是这样,为什么使用std :: vector ::擦除它会导致释放内存的错误
- 如何通过长度从 std::vector 中删除元素<string>(擦除不起作用)
- 从多个 std::vector 中删除项目的最快方法
- 从 std::vector 中删除原始指针
- C++ vector::erase 抱怨过载解析和删除运算符'=='
- 擦除范围从std :: vector删除向量的最佳方法
- STD :: vector在清除或删除POD方面的行为会有所不同
- std::vector 删除重复项,然后删除另一个向量中的相同索引
- 拒绝std::vector删除其数据
- C++ std::vector 删除 MyClass 对象
- 通过 <vector> 删除复制构造函数等,按值(无指针)将具有相同基类的对象存储在C++中