STL 源码分析《5》---- lower_bound and upper_bound 详解
来源:互联网 发布:车辆保险的算法 编辑:程序博客网 时间:2024/05/22 14:52
在 STL 库中,关于二分搜索实现了4个函数。
bool binary_search (ForwardIterator beg, ForwardIterator end, const T& value)
判断 [beg, end) 中是否存在 value 的值。
ForwardIterator
lower_bound (ForwardIterator beg, ForwardIterator end, const T& value)
ForwardIterator
upper_bound (ForwardIterator beg, ForwardIterator end, const T& value)
搜寻第一个或者最后一个可能位置。
具体是什么意思呢?
1. lower_bound 指的是 返回第一个 ”大于等于 value“ 的元素位置。
另一种解释是 可插入”元素值为 value“且 ”不破坏有序性“的第一个位置
2. upper_bound 指的是 返回第一个 “大于 value ” 的元素位置;
另一种解释是 可插入”元素值为 value“且 ”不破坏有序性“的最后一个位置
举个例子: 1 2 2 3 4 5
value = 2: 则 lower_bound 返回的位置是 第 1 个位置;
upper_bound 返回的位置是 第 3 个位置。
大家可以看到一个很有意思的性质:
upper_bound - lower_bound = 数组中 value 的个数
下面我们来研究下 lower_bound 和 upper_bound 的实现。
以下是我按照源码改写的一个版本:
// return the first element which >= xint LowerBound(int *a, int n, int x){ int left(0), right(n-1), mid; while(left <= right){ mid = left + ((right - left) >> 1); if(a[mid] < x){ left = mid + 1; } else{ right = mid - 1; } } return left;}// return first element which > xint UpperBound(int *a, int n, int x){ int left(0), right(n-1), mid; while(left <= right){ mid = left + ((right - left) >> 1); if(a[mid] <= x){ left = mid + 1; } else{ right = mid - 1; } } return left;}
大家知道,在 STL 库中,区间一般采用半闭半开区间 [begin, last),
这种做法的好处是 last - begin 就是区间元素的个数。
以下是 STL 中的源码:
template <class _ForwardIter, class _Tp, class _Distance>_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (*__middle < __val) { __first = __middle; ++__first; __len = __len - __half - 1; } else __len = __half; } return __first;}
lower_bound的一个应用:
最长递增子序列问题:分析见 http://blog.csdn.net/shoulinjun/article/details/13775177
代码如下:
int LIS(int *a, int n){ if(n <= 0) return 0; vector<int> maxV; maxV.push_back(a[0]); for(int i=0; i<n; ++i) { if(a[i] > *maxV.rbegin()) maxV.push_back(a[i]); else *lower_bound(maxV.begin(), maxV.end(), a[i]) = a[i]; } return maxV.size();}
- STL 源码分析《5》---- lower_bound and upper_bound 详解
- C++ STL 之 lower_bound and upper_bound
- C++ STL 之 lower_bound and upper_bound
- C++ STL 之 lower_bound and upper_bound
- STL: lower_bound(·) and upper_bound(·)
- C++ STL 之 lower_bound and upper_bound
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- 【STL源码学习】----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习----lower_bound和upper_bound算法
- STL源码学习---lower_bound和upper_bound
- STL源码学习----lower_bound和upper_bound算法
- Gedit中文乱码
- Codeforces Round #237 (Div. 2)__Restore Graph
- hello,world
- android:inputType参数类型说明
- 看谷歌实习生的惬意生活
- STL 源码分析《5》---- lower_bound and upper_bound 详解
- codeblocks下载和安装
- UML 之 包图
- spring 手动任务调度
- android开发中百度地图的使用
- 设计模式之抽象工厂模式(Abstract Factory)摘录
- Jquery - 调整Input标签的宽度并应用grid将input和button并排一行
- Java 6 JVM参数选项大全(中文版)
- 单链表建立删除和就地逆置