首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >find_if和bind2nd与lower_bound、upper_bound的等价性

find_if和bind2nd与lower_bound、upper_bound的等价性
EN

Stack Overflow用户
提问于 2020-08-11 16:09:48
回答 2查看 149关注 0票数 0

我的任务是从一些代码中删除bind2nd

我有一个排序的(升序的,可能有重复的) vector<double> m_x,还有一个值x,它是double类型。

  1. std::vector<double>::const_iterator it = std::find_if(m_x.begin(), m_x.end(), std::bind2nd(std::greater<double>(), x));

  1. std::vector<double>::const_iterator it = std::find_if(m_x.begin(), m_x.end(), std::bind2nd(std::greater_equal<double>(), x));

  1. std::vector<double>::const_iterator it = std::find_if(m_x.rbegin(), m_x.rend(), std::bind2nd(std::less<double>(), x)).base();

  1. std::vector<double>::const_iterator it = std::find_if(m_x.rbegin(), m_x.rend(), std::bind2nd(std::less_equal<double>(), x)).base();

相当于

  1. std::vector<double>::const_iterator it = std::upper_bound(m_x.begin(), m_x.end(), x);

  1. std::vector<double>::const_iterator it = std::lower_bound(m_x.begin(), m_x.end(), x);

  1. std::vector<double>::const_iterator it = std::upper_bound(m_x.rbegin(), m_x.rend(), x).base();

  1. std::vector<double>::const_iterator it = std::lower_bound(m_x.rbegin(), m_x.rend(), x).base();

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-11 16:50:50

  1. std::vector<double>::const_iterator it = std::find_if(m_x.begin(), m_x.end(), std::bind2nd(std::greater<double>(), x));

  1. std::vector<double>::const_iterator it = std::find_if(m_x.begin(), m_x.end(), std::bind2nd(std::greater_equal<double>(), x));

相当于

  1. std::vector<double>::const_iterator it = std::upper_bound(m_x.begin(), m_x.end(), x);

  1. std::vector<double>::const_iterator it = std::lower_bound(m_x.begin(), m_x.end(), x);

是。他们给出了同样的答案,但比较却较少。

  1. std::vector<double>::const_iterator it = std::find_if(m_x.rbegin(), m_x.rend(), std::bind2nd(std::less<double>(), x)).base();

  1. std::vector<double>::const_iterator it = std::find_if(m_x.rbegin(), m_x.rend(), std::bind2nd(std::less_equal<double>(), x)).base();

相当于

  1. std::vector<double>::const_iterator it = std::upper_bound(m_x.rbegin(), m_x.rend(), x).base();

  1. std::vector<double>::const_iterator it = std::lower_bound(m_x.rbegin(), m_x.rend(), x).base();

不是的。这些都有不明确的行为。你需要给他们一个相反的比较。

  1. std::vector<double>::const_iterator it = std::upper_bound(m_x.rbegin(), m_x.rend(), x, std::greater<double>{}).base();

  1. std::vector<double>::const_iterator it = std::lower_bound(m_x.rbegin(), m_x.rend(), x, std::greater<double>{}).base();
票数 3
EN

Stack Overflow用户

发布于 2020-08-11 16:14:48

代码语言:javascript
复制
[x](auto&& y) { return std::less_equal<double>{}(y, x); }

这几乎是1:1的替换。你很可能会做得更好:

代码语言:javascript
复制
[&](auto&& y) { return y<=x; }

这可能更接近于编写代码的人的意思,但如果容器和/或x的类型不是double,则可能会有一些非常微妙的差别。

至于你的问题,lower_boundupper_bound是用<来定义的。<的行为与用于NaN!>=不同。

因此,使用NaN,您的代码将不会有相同的行为。

所以它们是不对等的。

假设我们从考虑中排除了NaN

首先要做的是考虑equal_range的情况,因为equal_range比上/下界容易得多。

upper_bound是插入x的半开区间的末尾。lower_bound是它的开始。

因此,如果x超出容器的末尾,则两者都返回.end()

如果x位于容器前面,则两者都返回.begin()

如果容器中有一个或多个x副本,那么lower_bound将一个迭代器返回到x的第一个实例,而upper_bound返回后的第一个迭代器( x的最后一个实例)。

如果x不在容器中,而是位于两个元素ab之间,那么上界和下界都返回一个引用b的迭代器。

现在我们比较一下。

1和2在这两种情况下是相同的。

3和4是无效的C++代码。

所以,不,他们是不对等的。

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

https://stackoverflow.com/questions/63362155

复制
相关文章

相似问题

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