是否有使用二进制搜索的函数,例如lower_bound
但是返回 last 项小于或等于根据给定的谓词?
lower_bound
定义为:
在大于或等于指定值的有序范围内查找第一个元素的位置,其中排序标准可由a指定二元谓词。
和upper_bound
:
在大于指定值的有序范围内查找 first 元素的位置,其中排序条件可由二进制指定谓词。
具体来说,我有一个时间排序事件的容器,并且在给定时间内我想找到之前或之前的最后一个项目。我可以通过上/下限,反向迭代器和使用std::greater
或std::greater_equal
的某种组合实现此目的吗?
编辑: 如果你在数组开始之前要求一个点,那么用户763305的建议需要进行调整:
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;
答案 0 :(得分:39)
在已排序的容器中,小于或等于x
的最后一个元素是第一个元素之前大于x
的元素。
因此,您可以调用std::upper_bound
,并递减返回的迭代器一次。
(在递减之前,您当然必须检查它不是开始迭代器;如果是,则没有任何元素小于或等于x
。)
答案 1 :(得分:7)
这是一个围绕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 — Find last number less than or equal to a given element in an array or container
答案 2 :(得分:5)
我测试了你的反向迭代器解决方案,这是正确的。
鉴于v
按'&lt;'
查找小于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
版
答案 3 :(得分:0)
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
答案 4 :(得分:0)
一个简单的Python实现:
def bi_search(arr, target):
"""
index of the last element which <= target
"""
lo, hi = 0, len(arr)
while lo < hi:
mid = lo + (hi - lo) // 2
if arr[mid] <= target:
lo = mid + 1
else:
hi = mid
return lo - 1