介绍C++库函数upper_bound和lower_bound
前言
- 这两个库函数是用二分的方法查找元素
- 时间复杂度是 O ( l o g n ) O(logn) O(logn) 级别
- 在头文件内
- 注意 因为是二分,所以一定是满足单调性的,不然使用这两个函数没有什么意义
具体介绍
upper_bound
第一个函数声明
template<typename _ForwardIterator, typename _Tp>
inline _ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
_ForwardIterator是迭代器类型,可以是指针_Tp是元素类型,例如intdouble, 也可以是自定义类型- 第一个和第二个参数表示要搜索的起始位置
__first和终止位置__last, 第三个是要搜索的元素__val - 返回值也是一个迭代器类型, 返回的是能在不改变顺序的条件的把这个元素
__val插到这段区间的最后一个位置, 也就是严格大于这个元素的第一个位置,如果不存在这样的数字,那么就返回end()
简单示例:
#include <iostream>
#include <algorithm>
int main()
{
int arr[] = {1, 2, 2, 4, 4, 5, 6, 7, 8};
int len = sizeof arr / sizeof arr[0];
auto t = std::upper_bound(arr, arr + len, 4);
std::cout << *t << std::endl;
std::cout << "index = " << t - arr << std::endl;
return 0;
}
执行结果:
5
index = 5
- 首先第一个输出的是要把
4插入不改变顺序的位置的元素 - 注意 是最后一个位置,所以第二个结果是
index = 5, 是能把这个元素插进去不改变顺序的最后一个位置, 同时也是大于4的第一个位置
当然我们也可以指定搜索的规则,就有了如下的函数重载
第二个函数声明
template<typename _ForwardIterator, typename _Tp, typename _Compare>
inline _ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
- 额外加的参数是一个可调用对象
_Compare类型,可以是**lambda表达式**, 函数, 谓词等 - 这个参数可以让函数根据我们自己定义的规则来进行比较查找
简单示例:
上面的例子的upper_bound和下面的的是一样的
auto t = std::upper_bound(arr, arr + len, 4, [&](int x, const int& val){
return x < val;
});
- 可调用对象:第一个参数是要搜的元素, 就上面的例子而言,
x就是4, 第二个参数是迭代的区间的一个单位,上面的例子就是int, 所以加上不可修改就改成了const int&, 如果arr的类型是std::vector<vector<int>>那么第二个参数就可以是const vector<int>&, 当然也可以用const auto&,但是原则是使用者本身知道auto代指的是什么类型,注意:两个参数的位置不能交换,否则会产生错误 - 比较规则:返回的是满足规则的第一个元素的位置,例如
return x < val;表示的就是数组中的元素val大于x的第一个位置, 如果改成return x <= val;那么表示的意思就是第一个满足这个的条件的第一个位置,此时程序运行的结果是4, index = 3
lower_bound
此函数和upper_bound函数是类似的,用法基本一致
第一个函数声明
template<typename _ForwardIterator, typename _Tp>
inline _ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
- 参数和
upper_bound完全相同 - 函数的功能是 找到能把这个元素插进去并且不改变这个顺序的第一个位置, 也就是返回的是第一个不小于
__val的第一个位置,如果不存在这样的数,那么返回end()
第二个函数声明
template<typename _ForwardIterator, typename _Tp, typename _Compare>
inline _ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
- 要注意的一点是第一个参数是迭代的区间的一个单位, 第二个参数是要搜的元素,其他大部分和上面的基本相同,不多赘述
简单例子
vector<vector<int>> a;
// 初始化 a
auto t = lower_bound(a.begin(), a.end(), 1, [&](const vector<int>& val, int x)
{
return x > val[1];
});
总结:
- 这两个函数非常重要,以二分在 O ( l o g n ) O(logn) O(logn)的时间复杂度快速查找,算法中常用的函数
- 多积累
本文详细介绍了C++标准库中的upper_bound和lower_bound函数,它们使用二分查找,时间复杂度为O(logn),适用于按特定规则插入或查找元素。通过示例展示了函数的用法和重载版本。

9700

被折叠的 条评论
为什么被折叠?



