STL 源码剖析 算法 stl_algo.h -- upper_bound

来源:互联网 发布:神经网络算法入门书籍 编辑:程序博客网 时间:2024/05/01 22:15

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


upper_bound(应用于有序区间)

-------------------------------------------------------------------------------------------------------------------------------------------------
描述:受STL区间前闭后开习惯的影响,upper_bound成功找到某个值时,
返回一个迭代器指向每一个"不大于 value "的元素的下一个位置,而不是指向 value 的迭代器,
或找不到,返回value 应该存在的位置
思路:
1.循环直到区间长度为 0 
2.如果 value < *middle,在前半段继续查找
3.如果 value >= *middle,在后半段继续查找 (等于的时候也会继续在后半段查找,所以能保证找到的是 upper bound)

源码:

template <class ForwardIterator, class T>inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,                                   const T& value) {  return __upper_bound(first, last, value, distance_type(first),                       iterator_category(first));}// forward_iterator_tag 版本template <class ForwardIterator, class T, class Distance>ForwardIterator __upper_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);    if (value < *middle)      len = half;    else {       first = middle;      ++first;      len = len - half - 1;    }  }  return first;}// random_access_iterator_tag 版本template <class RandomAccessIterator, class T, class Distance>RandomAccessIterator __upper_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;    middle = first + half;    if (value < *middle)      len = half;    else { //因为大于等都是在后半段区间查找,所以最后找到的一定是 upper bound,而且存在 value 的话, first 最后指示的就是 value 的下一个位置      first = middle + 1;      len = len - half - 1;    }  }  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 = upper_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 = 1, A[1] == 2Searching for 2.  Result: index = 2, A[2] == 3Searching for 3.  Result: index = 5, A[5] == 5Searching for 4.  Result: index = 5, A[5] == 5Searching for 5.  Result: index = 6, A[6] == 8Searching for 6.  Result: index = 6, A[6] == 8Searching for 7.  Result: index = 6, A[6] == 8Searching for 8.  Result: index = 7, which is off-the-end.Searching for 9.  Result: index = 7, which is off-the-end.Searching for 10.  Result: index = 7, which is off-the-end.*/

0 0
原创粉丝点击