STL中的每个算法都非常精妙,接下来的几天我想集中学习一下STL中的算法。

  ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。

ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)算法返回一个非递减序列[first, last)中第一个大于val的位置。

lower_bound和upper_bound如下图所示:

1, lower_bound

  这个序列中可能会有很多重复的元素,也可能所有的元素都相同,为了充分考虑这 种边界条件,STL中的lower_bound算法总体上是才用了二分查找的方法,但是由于是查找序列中的第一个出现的值大于等于val的位置,所以算法 要在二分查找的基础上做一些细微的改动。

首先是我修改数据结构课本上的二分查找实现的lower_bound算法:

int my_lower_bound(int *array, int size, int key)
{
int first = 0, last = size-1;
int middle, pos=0; //需要用pos记录第一个大于等于key的元素位置 while(first < last)
{
middle = (first+last)/2;
if(array[middle] < key){ //若中位数的值小于key的值,我们要在右边子序列中查找,这时候pos可能是右边子序列的第一个
first = middle + 1;
pos = first;
}
else{
last = middle; //若中位数的值大于等于key,我们要在左边子序列查找,但有可能middle处就是最终位置,所以我们不移动last,
pos = last; //而是让first不断逼近last。
}
}
return pos;
}

  STL中的实现比较精巧,下面贴出源代码:

//这个算法中,first是最终要返回的位置
int lower_bound(int *array, int size, int key)
{
int first = 0, middle;
int half, len;
len = size; while(len > 0) {
half = len >> 1;
middle = first + half;
if(array[middle] < key) {
first = middle + 1;
len = len-half-1; //在右边子序列中查找
}
else
len = half; //在左边子序列(包含middle)中查找
}
return first;
}

2, upper_bound

upper_bound返回的是最后一个大于等于val的位置,也是有一个新元素val进来时的插入位置。

我依然将二分查找略做修改:

int my_upper_bound(int *array, int size, int key)
{
int first = 0, last = size-1;
int middle, pos = 0; while(first < last)
{
middle = (first+last)/2;
if(array[middle] > key){ //当中位数大于key时,last不动,让first不断逼近last
last = middle;
pos = last;
}
else{
first = middle + 1; //当中位数小于等于key时,将first递增,并记录新的位置
pos = first;
}
}
return pos;
}

下面的代码是STL中的upper_bound实现:

int upper_bound(int *array, int size, int key)
{
int first = 0, len = size-1;
int half, middle; while(len > 0){
half = len >> 1;
middle = first + half;
if(array[middle] > key) //中位数大于key,在包含last的左半边序列中查找。
len = half;
else{
first = middle + 1; //中位数小于等于key,在右半边序列中查找。
len = len - half - 1;
}
}
return first;
}

STL源码学习----lower_bound和upper_bound算法[转]的更多相关文章

  1. STL源码学习----lower_bound和upper_bound算法

    转自:http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html 先贴一下自己的二分代码: #include <cstdio&g ...

  2. [转] STL源码学习----lower_bound和upper_bound算法

    http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html PS: lower_bound of value 就是最后一个 < ...

  3. stl源码学习(版本2.91)--list

    stl源码学习(版本2.91)--list 一,阅读list()构造函数的收获 1,默认构造函数的作用和被调用的时机 struct no{ no(int i){} //no(){ // std::co ...

  4. 【STL源码学习】STL算法学习之二

    第一章:前言 学习笔记,记录学习STL算法的一些个人所得,在以后想用的时候可以快速拾起. 第二章:明细 copy 函数原型: template <class InputIterator, cla ...

  5. 【STL源码学习】std::list类的类型别名分析

    有了点模板元编程的traits基础,看STL源码清晰多了,以前看源码的时候总被各种各样的typedef给折腾得看不下去, 将<list>头文件的类继承结构简化如下 #include < ...

  6. 【STL源码学习】细品vector

    第一节:vector简介 vector是一种典型的类模板,使用的时候必须进行实例化. vector的数据存储在数组上,支持随机访问迭代器,支持下标操作[]和at操作,支持手动扩容和自动容量增长. ve ...

  7. 【STL源码学习】STL算法学习之三

    第一章:前言 数量不多,用到的时候会很爽. 第二章:明细 STL算法中的又一个分类:分割:将已有元素按照既定规则分割成两部分.  is_partitioned 函数原型: template <c ...

  8. 【STL源码学习】STL算法学习之一

    第一章:引子 STL包含的算法头文件有三个:<algorithm><numeric><functional>,其中最大最常用的是<algorithm>, ...

  9. 【STL源码学习】STL算法学习之四

    排序算法是STL算法中相当常用的一个类别,包括部分排序和全部排序算法,依据效率和应用场景进行选择. 明细: sort 函数原型: template <class RandomAccessIter ...

随机推荐

  1. <转>安卓应用测试checklist

    启动: 1. 启动入口:桌面正常启动,最近运行启动,所有程序列表中启动,锁屏快捷启动 2. 其他入口:从其他程序开启应用,从外部以文件形式打开应用(如果有) 3. 退回:从其他程序退回时回到被测应用, ...

  2. leetcode:Longest Palindromic Substring(求最大的回文字符串)

    Question:Given a string S, find the longest palindromic substring in S. You may assume that the maxi ...

  3. 【加解密】关于DES加密算法的JAVA加密代码及C#解密代码

    JAVA加密: package webdomain; import java.security.Key; import java.security.spec.AlgorithmParameterSpe ...

  4. ZOJ-3349 Special Subsequence 线段树优化DP

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3349 题意:给定一个数列,序列A是一个满足|Ai-Ai-1| & ...

  5. php基础知识(3)(文件加载include)

    文件加载 综述: 有4个文件加载的语法形式(注意,不是函数): include,  include_once,  require, require_once; 他们的本质是一样的,都是用于加载/引入/ ...

  6. Codeforces Round #368 (Div. 2) A. Brain's Photos (水题)

    Brain's Photos 题目链接: http://codeforces.com/contest/707/problem/A Description Small, but very brave, ...

  7. gcc -D

    [gcc -D] -D name Predefine name as a macro, with definition 1. 通常debug和release版的区别就在于是否有DEBUG宏,DEBUG ...

  8. hdu 1281 棋盘游戏

    http://acm.hdu.edu.cn/showproblem.php?pid=1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  9. JUnit 4 如何正确测试异常

    本篇讲述如何在 JUnit 4 下正确测试异常,我会从 try..catch 的方式谈起,然后说到 @Test(expected=Exception.class), 最后论及 @Rules publi ...

  10. poj1584

    题意:已知一个多边形的n个顶点坐标,然后再给一个钉子,给定钉子的半径和圆心坐标,首先判断多边形是否为凸多边形,若为凸多边形,再判断钉子是否可以放到凸多边形内部. 思路: 1.由于顶点给出的顺序可能为逆 ...