本文为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的更多相关文章

  1. STL 源代码剖析 算法 stl_algo.h -- search

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...

  2. STL 源代码剖析 算法 stl_algo.h -- equal_range

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) ------------------------- ...

  3. STL 源代码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partial_sort / partial_sort_copy ------------- ...

  4. STL 源代码剖析 算法 stl_algo.h -- inplace_merge

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) ----------------------- ...

  5. STL 源代码剖析 算法 stl_algo.h -- random_shuffle

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie random_shuffle ------------------------------- ...

  6. STL 源代码剖析 算法 stl_algo.h -- merge sort

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...

  7. STL 源代码剖析 算法 stl_algo.h -- partition

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partition ------------------------------------ ...

  8. STL 源代码剖析 算法 stl_algo.h -- next_permutation

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie next_permutation ----------------------------- ...

  9. STL 源代码剖析 算法 stl_algo.h -- nth_element

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie nth_element ---------------------------------- ...

随机推荐

  1. 【HDOJ】2890 Longest Repeated subsequence

    后缀数组的应用.和男人八题那个后缀数组差不多. /* 2890 */ #include <iostream> #include <sstream> #include <s ...

  2. Area of a Circle

    Area of a Circle Description: Complete the function circleArea so that it will return the area of a ...

  3. Android开发之极光推送基本步骤

    [转]:http://wyong.blog.51cto.com/1115465/1402842 两天在研究推送的问题,后来确定了用极光推送,本人将整个过程整理一下: 1.到极光官网注册账号:https ...

  4. HashMap Hashtable ArrayList HashSet

    一.散列 1. HashMap 1)  hashmap的数据结构 Hashmap是一个数组和链表的结合体(在数据结构称“链表散列“),如下图示: 当我们往hashmap中put元素的时候,先根据key ...

  5. p2p穿透技术

    ios 怎么和wifi外设摄像头实时传输视频 ios 控制wifi摄像头外设的拍照.录像.删除照片等等都可以通过tcp/ip 发送定义好的json指令实现. 但是不知道怎么和wifi外设摄像头实时传输 ...

  6. cf A. Inna and Pink Pony(思维题)

    题目:http://codeforces.com/contest/374/problem/A 题意:求到达边界的最小步数.. 刚开始以为是 bfs,不过数据10^6太大了,肯定不是... 一个思维题, ...

  7. [.NET WebAPI系列01] WebAPI 简单例子

    [源] 来自微软WebAPI官方视频,Introduction to the ASP.NET Web API --Uniform Interface -- Demo-Using convention ...

  8. Oracle 10g DataGuard手记之基础配置

    DataGuard为企业数据的高可用性,数据安全以及灾难恢复提供支持,一般由一个primary db与几个物理或逻辑standby db组成一个DataGuard配置. 系统环境 操作系统为windo ...

  9. Hibernate配置文件解释

    Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需的各种属性每个Hibernate配置文件对应一个Configuration对象Hibernate配置文件可以有两种格式: ...

  10. 淘宝JAVA中间件Diamond详解(一)---简介&快速使用

    大家好,今天开始为大家带来我们通用产品团队的产品 —— diamond的专题,本次为大家介绍diamond的概况和快速使用. 一.概况 diamond是淘宝内部使用的一个管理持久配置的系统,它的特点是 ...