【问题标题】:Erasing using iterator from 'find' or 'remove'使用“查找”或“删除”中的迭代器进行擦除
【发布时间】:2014-07-23 13:55:06
【问题描述】:

我想知道在 C++ 中从向量中删除元素的最佳做法是什么。

我见过很多人使用 std::remove 查找和删除元素,然后使用擦除从向量中删除元素。

但是为什么比使用 find 获取要删除的元素的迭代器,然后使用带有该迭代器的擦除更好呢?

谢谢

【问题讨论】:

    标签: c++ vector std


    【解决方案1】:

    std::find 后跟 vector::erase 将删除 vector 中具有给定值的对象的第一个匹配项。

    std::vector<int> vec{1,3,3,8,3,5};
    vec.erase(std::find(vec.begin(), vec.end(), 3));
    //vec == {1,3,8,3,5}
    

    std::remove 后跟vector::erase 将从vector 中删除每个 出现的具有给定值的对象。

    std::vector<int> vec{1,3,3,8,3,5};
    vec.erase(std::remove(vec.begin(), vec.end(), 3), vec.end());
    //vec == {1,8,5}
    

    两者都不是更好,它们只是做不同的事情。

    std::remove 更普遍有用,这就是它更常见的原因;特别是,std::remove 后跟 vector::erase 当元素不存在于向量中时不执行任何操作,而 std::find 后跟 vector::erase 具有未定义的行为。

    请注意,“find-erase”、“remove-erase”都保持元素的相对顺序。如果你想从向量中删除一个元素但不关心元素的结果顺序,你可以使用“find-move-pop_back”或“partition-erase”:

    //find-move-pop_back
    std::vector<int> vec{1,3,3,8,3,5};
    *std::find(vec.begin(), vec.end(), 3) = std::move(vec.back());
    vec.pop_back();
    
    //partition-erase
    std::vector<int> vec{1,3,3,8,3,5};
    vec.erase(
        std::partition(vec.begin(), vec.end(), [](int v){return v != 3;}),
        vec.end());
    

    【讨论】:

    • 完美答案:)。谢谢
    • 请注意,partition-erase 将删除谓词返回 false 的元素,remove-erase 将删除谓词返回 true 的元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    相关资源
    最近更新 更多