STL 源代码剖析 算法 stl_algo.h -- lower_bound
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
lower_bound(应用于有序区间)
--------------------------------------------------------------------------------------------------------------------------
描写叙述:二分查找,返回一个迭代器指向每个"不小于 value "的元素,
或 value 应该存在的位置
思路:
1.循环直到区间长度为 0
2.假设 *middle < value,在后半段继续查找
3.假设 *middle >= value,在前半段继续查找 (等于的时候也会继续在前半段查找,所以能保证找到的是 lower bound)
源代码:
template <class ForwardIterator, class T>
inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
const T& value) {
return __lower_bound(first, last, value, distance_type(first),
iterator_category(first));
} // forward_iterator_tag 版本号
template <class ForwardIterator, class T, class Distance>
ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
const T& value, Distance*,
forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle; while (len > 0) {
half = len >> 1;
middle = first;
advance(middle, half); // 由于仅仅是 ForwardIterator,不能採用 middle = middle + half 的方式
if (*middle < value) {
first = middle;
++first;
len = len - half - 1;
} // 由于 *middle >= value 时,会在前半段继续查找。所以终于找到的是 lower bound
else
len = half;
}
return first;
} // random_access_iterator_tag 版本号
template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __lower_bound(RandomAccessIterator first,
RandomAccessIterator last, const T& value,
Distance*, random_access_iterator_tag) {
Distance len = last - first; // 整个区间长度
Distance half;
RandomAccessIterator middle; while (len > 0) {
half = len >> 1; //除以2
middle = first + half;
if (*middle < value) {
first = middle + 1;
len = len - half - 1; // -half-1 是由于前面那段有first指向的元素和half指向的区间
}
else //为什么这种代码能保证找到的是 lower bound ?--> 由于小于等于都是到前面一段区间查找,所以最后找到的一定是 lower bound
len = half;
}
return first;
}
演示样例:
int main()
{
int A[] = { 1, 2, 3, 3, 3, 5, 8 };
const int N = sizeof(A) / sizeof(int); for (int i = 1; i <= 10; ++i) {
int* p = lower_bound(A, A + N, i);
cout << "Searching for " << i << ". ";
cout << "Result: index = " << p - A << ", ";
if (p != A + N)
cout << "A[" << p - A << "] == " << *p << endl;
else
cout << "which is off-the-end." << endl;
}
}
/*
The output is:
Searching for 1. Result: index = 0, A[0] == 1
Searching for 2. Result: index = 1, A[1] == 2
Searching for 3. Result: index = 2, A[2] == 3
Searching for 4. Result: index = 5, A[5] == 5
Searching for 5. Result: index = 5, A[5] == 5
Searching for 6. Result: index = 6, A[6] == 8
Searching for 7. Result: index = 6, A[6] == 8
Searching for 8. Result: index = 6, A[6] == 8
Searching for 9. Result: index = 7, which is off-the-end.
Searching for 10. Result: index = 7, which is off-the-end.
*/
STL 源代码剖析 算法 stl_algo.h -- lower_bound的更多相关文章
- STL 源代码剖析 算法 stl_algo.h -- search
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- equal_range
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) ------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partial_sort / partial_sort_copy ------------- ...
- STL 源代码剖析 算法 stl_algo.h -- inplace_merge
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) ----------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- random_shuffle
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie random_shuffle ------------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- merge sort
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- partition
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partition ------------------------------------ ...
- STL 源代码剖析 算法 stl_algo.h -- next_permutation
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie next_permutation ----------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- nth_element
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie nth_element ---------------------------------- ...
随机推荐
- 1701. Ostap and Partners(并查集-关系)
1701 又是类似食物链的这一类题 这题是找与根节点的和差关系 因为0节点是已知的 为0 那么所有的都可以转换为与0的和差关系 可以规定合并的两节点 由大的指向小的 然后再更新和差关系 有可能最后有 ...
- poj 1753 Flip Game 枚举(bfs+状态压缩)
题目:http://poj.org/problem?id=1753 因为粗心错了好多次……,尤其是把1<<15当成了65535: 参考博客:http://www.cnblogs.com/k ...
- 体验Azure的 Automation “自动化” 服务预览版
一直想要实现对Azure上跑的虚机进行定期的自动备份.在网上搜了一下有关的解决方案,发现一个不错的帖子,是基于国外的Azure服务做的.基本原理就是利用Azure的Automation(自动化)服务来 ...
- Java [leetcode 19]Remove Nth Node From End of List
题目描述: Given a linked list, remove the nth node from the end of list and return its head. For example ...
- AM335x(TQ335x)学习笔记——挂载Ramdisk
上篇文章中我们已经能够通过u-boot启动内核了,但是没有能够启动成功,从内核的log中可以看出,内核启动失败的原因是没有挂载到root文件系统,本文将使用busybox制作根文件系统并打包成ramd ...
- 理解Android的手势识别
对于触摸屏,其原生的消息无非按下.抬起.移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理.不过,为了提高我们的APP的用户体验,有时候我们 ...
- application/x-www-form-urlencoded等字符编码的解释说明
关于application/x-www-form-urlencoded等字符编码的解释说明 在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏 ...
- redhat mysql 远程开启
2)开启远程接入.登录到数据库,对mysql.user进行操作 表Mysql.user记录了不同用户不同主机不同的权限.可通过命令查看: Select * from mysql.user : 插入新用 ...
- 浅谈reverse_iterator的base()函数
非原创,原文链接:http://blog.csdn.net/shuchao/article/details/3705252 调用reverse_iterator的base成员函数可以产生"对 ...
- bzoj 3932 [CQOI2015]任务查询系统(主席树)
Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分. 超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si ...