首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++11 STL唯一函数,但相反

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

Stack Overflow用户
提问于 2018-02-28 20:42:14
回答 1查看 247关注 0票数 3

是否有一个类似于std::unique的函数,但它接受一个自定义比较谓词,并以等价的顺序保留最后一个元素,而不是第一个?如果C++14或C++17是一个选项,答案是肯定的;但是,我使用的是C++11。

我从一个大型的重物开始,按一个轻量级的字段排序。有些对象对于轻量级字段具有相同的值,这是不可接受的。我需要用匹配的光场丢弃任何序列中除最后一个物体之外的所有物体。

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

代码语言:javascript
运行
复制
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。我希望我的代码看起来像这样:

代码语言:javascript
运行
复制
pair<HevIt, HevIt> deleteRange = magical_range_search(
    heavyDeque.begin(), heavyDeque.end(),
    [helperLight](const Heavy & heavy) {
        return helperLight == heavy.getLight()})

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-28 21:03:50

可能是这样吧?

代码语言:javascript
运行
复制
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::uniquereverse_iterator一起使用,如注释中所示:

代码语言:javascript
运行
复制
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()返回unique()返回的reverse_iterator的底层原始迭代器。当unique()返回序列的新结尾时,反向操作返回序列的新开始。新的范围是{new_begin, orignal_end},范围{original_begin, new_begin}中的元素必须是erase()d。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49038189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档