代码之家  ›  专栏  ›  技术社区  ›  Kevin Hencke

C++11 STL唯一函数,但相反

  •  3
  • Kevin Hencke  · 技术社区  · 6 年前

    是否有如下功能 std::unique ,但它采用自定义比较谓词,并保留 最后的 元素,而不是第一个?如果选择C++14或C++17,答案是肯定的;然而,我使用的是C++11。

    我从一组大而重的物体开始,按一个轻量级字段排序。某些对象的轻量级字段值相等,这是不可接受的。我需要丢弃除 最后的 具有匹配光场的任意序列中的对象。

    目前我的代码调用 equal_range 使用自定义 二进制的 谓词和助手重对象,然后倒带结束迭代器:

    deque<Heavy> heavyDeque(...);
    
    Light helperLight(...);
    Heavy helperHeavy(helperLight, );
    
    typedef deque<Heavy>:: iterator HevIt;
    
    pair<HevIt, HevIt> deleteRange = equal_range(
        heavyDeque.begin(), heavyDeque.end(), helperHeavy,
        [](const Heavy & lhs, const Heavy & rhs) {
            return lhs.getLight() < rhs.getLight()})
    
    //I have prior knowledge of at least one match
    assert(deleteRange.first != deleteRange.second);
    // back up; don't delete the last one
    --(deleteRange.second);
    heavyDeque.erase(deleteRange.first, deleteRange.second);
    

    我不太高兴不得不通过 helperHeavy ,而我只需要从里面 helperLight . 我希望我的代码如下所示:

    pair<HevIt, HevIt> deleteRange = magical_range_search(
        heavyDeque.begin(), heavyDeque.end(),
        [helperLight](const Heavy & heavy) {
            return helperLight == heavy.getLight()})
    

    注意,我想象中的魔法函数 一元的 谓词,而不是二进制谓词。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Walter    6 年前

    也许是这样的?

    template<typename BidirectionalIterator, typename UnaryPredicate>
    pair<BidirectionalIterator,BidirectionalIterator>
    magical_range_search(BidirectionalIterator begin,
                         BidirectionalIterator end, UnaryPredicate p)
    {
      return {find_if(begin,end,p),
              find_if(make_reverse_iterator(end),make_reverse_iterator(begin),p)};
    }
    

    但是,当然,就整个事情而言,你可以 std::unique 用一个 reverse_iterator ,如注释所示:

    heavyContainer.erase(heavyContainer.begin(),
                         unique(make_reverse_iterator(heavyContainer.end()),
                                make_reverse_iterator(heavyContainer.begin()),
                                [](Heavy const&lhs, Heavy const&rhs) {
                                    return lhs.getLight() < rhs.getLight();
                                }).base());
    

    在这里 reverse_iterator<>::base() 返回 reverse\u迭代器 返回人 unique() . 像 唯一() 返回序列的新结束,反向操作返回序列的新开始。新范围为 {new_begin, orignal_end} ,以及范围中的元素 {original_begin, new_begin} 必须是 erase() d