用于查找小于或等于的最后一项的函数,如lower_bound

function for finding last item less-than-or-equal to, like lower_bound

本文关键字:函数 一项 bound lower 小于 查找 最后 用于      更新时间:2023-10-16

中是否有一个函数使用二叉搜索,如 lower_bound,但根据给定的谓词返回小于或等于的最后一项?

lower_bound定义为:

查找值大于或等效于指定值的有序区域中第一个元素的位置,其中排序条件可能由二进制谓词指定。

upper_bound

查找值大于指定值的有序区域中第一个元素的位置,其中排序条件可能由二进制谓词指定。

具体来说,我有一个时间排序事件的容器,在给定的时间内,我想找到之前或在那一点上的最后一个项目。 我可以通过上限/下限、反向迭代器以及使用 std::greaterstd::greater_equal 的某种组合来实现这一点吗?

编辑:需要对user763305的建议进行调整,以应对在数组开始之前要求一个点:

iterator it=upper_bound(begin(), end(), val, LessThanFunction());
if (it!=begin()) {
  it--; // not at end of array so rewind to previous item
} else {
  it=end(); // no items before this point, so return end()
}
return it;

在排序容器中,小于或等效于 x 的最后一个元素是第一个元素之前大于 x 的元素。

因此,您可以调用 std::upper_bound ,并将返回的迭代器递减一次。(在递减之前,您当然必须检查它是否不是开始迭代器;如果是,则没有小于或等效于 x 的元素。

我已经测试了您的反向迭代器解决方案,它是正确的。

给定v按"<"排序

查找最后一个小于 x 的元素:

auto iter = std::upper_bound(v.rbegin(), v.rend(), x, std::greater<int>());
if(iter == v.rend())
    std::cout<<"no found";
else
    std::cout<<*iter;

查找小于等于 x 的最后一个元素:

auto iter = std::lower_bound(v.rbegin(), v.rend(), x, std::greater<int>());
if(iter == v.rend())
    std::cout<<"no found";
else
    std::cout<<*iter;

这比iter -= 1版本更好

下面是

一个围绕upper_bound的包装函数,它返回容器或数组中小于或等于给定值的最大数字:

template <class ForwardIterator, class T>
  ForwardIterator largest_less_than_or_equal_to ( ForwardIterator first, 
                                                  ForwardIterator last,
                                                  const T& value)
{
  ForwardIterator upperb = upper_bound(first, last, value);
  // First element is >, so none are <=
  if(upperb == first)
    return NULL;
  // All elements are <=, so return the largest.
  if(upperb == last)
    return --upperb;
  return upperb - 1;
}

要更好地解释此功能的作用以及如何使用此功能,请查看:

C++ STL — 查找数组或容器中小于或等于给定元素的最后一个数字

std::prev : https://en.cppreference.com/w/cpp/iterator/prev

#include <iostream>
#include <map>
int main()
{
    std::map<int, char> m{{2, 'a'}, {4, 'b'}, {6, 'c'}, {8, 'd'}, {10, 'e'}};
    int num = 3;
    auto it = m.upper_bound(num);
    auto pv = std::prev(it);
    std::cout << "upper bound of " << num << ": "
        << it->first << ", " << it->second << 'n';
    std::cout << "lower than or equal of " << num << ": "
        << pv->first << ", " << pv->second << 'n';
}

输出:

upper bound of 3: 4, b
lower than or equal than 3: 2, a