【问题标题】:Efficiently delete double entries in C++ STL vector? [duplicate]有效地删除 C++ STL 向量中的双重条目? [复制]
【发布时间】:2012-11-09 09:06:28
【问题描述】:

可能重复:
C++ Delete Duplicate Entries in a vector

我需要删除 C++ STL 向量中的双重条目。重要的一点是结果向量中元素的顺序必须与输入向量中的顺序相同。是否有一种算法(例如在 stl、boost 中)可以做到这一点?

【问题讨论】:

  • std::unique 要求所有重复条目都按连续顺序排列。这是我无法实现的假设。

标签: c++ algorithm boost stl


【解决方案1】:

这里有两种可能的情况:向量已经排序或者没有。

如果是,std::erasestd::unique 可以轻松解决此问题,如其他答案所示。

如果不是,那么您可以实现目标

v.erase(std::remove_if(v.begin(), v.end(), predicate), v.end());

但是有一个问题,predicate 的指定并非易事:它是一个接受一个参数(要考虑的值)的函数,它需要回答“向量中是否有任何相等的值?”这个问题。 .由于没有告诉您提供的参数在向量中的确切位置,这意味着您必须保持相当多的手动状态才能回答这个问题。

这里一个方便的选择是使用std::set 来完成一些繁重的工作:

std::set<decltype(v)::value_type> set(v.begin(), v.end());
v.erase(
    std::remove_if(
        v.begin(), 
        v.end(), 
        [&set] (decltype(v)::value_type item) { return !set.erase(item); }), 
    v.end());

它的作用是使用向量中的值预填充std::set,然后通过查看是否已从集合中删除一个项目来检查它是否以前见过。这样,结果将仅保留输入中比较相等的每组项目中的第一项。

See it in action.

【讨论】:

    【解决方案2】:

    如果你的向量没有排序,因此你不能只使用std::unique(同样不能排序会破坏你的订单),你可以使用类似这个函数的东西(使用 C++11 lambdas):

    template<typename FwdIt> FwdIt unordered_unique(FwdIt first, FwdIt last)
    {
        typedef typename std::iterator_traits<FwdIt>::value_type value_type;
        std::set<value_type> unique;
        return std::remove_if(first, last, [&unique](const value_type &arg) { 
                                               return !unique.insert(arg).second; });
    }
    

    可以使用通常的 erase-romve-idiom 调用:

    v.erase(unordered_unique(v.begin(), v.end()), v.end());
    

    当然,您也可以使用 C++11 的 std::unordered_set 而不是 std::set(当然对于可散列类型)来避免平均情况下的 O(n log n)。

    【讨论】:

      【解决方案3】:

      std::unique怎么样?

      auto firstDup = std::unique(myvector.begin(), myvector.end());
      

      【讨论】:

        【解决方案4】:

        使用下一个:
        vec.erase( unique( vec.begin(), vec.end() ), vec.end() );

        【讨论】:

        • 这假定向量已排序。
        猜你喜欢
        • 1970-01-01
        • 2013-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-23
        • 2021-10-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多