码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-02-12 16:17:32      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

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


equal_range(应用于有序区间)

--------------------------------------------------------------------------------------------------------------------------------------
描写叙述:利用二分查找找到一个区间,区间里的全部值都等于给定值,返回的是一个pair。
分别存储区间的上界迭代器和下界迭代器

源代码:

template <class ForwardIterator, class T>
inline pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
  return __equal_range(first, last, value, distance_type(first),
                       iterator_category(first));
}


// ForwardIterator 版本号
template <class ForwardIterator, class T, class Distance>
pair<ForwardIterator, ForwardIterator>
__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
              Distance*, forward_iterator_tag) {
  Distance len = 0;
  distance(first, last, len);
  Distance half;
  ForwardIterator middle, left, right;


  while (len > 0) { // 奇怪? 为什么不直接用 lower_bound 、 upper_bound , 而是等找到值再用?
					// --> 我认为是效率方面的考虑。

先找 value ,这时左右两个区间可能已经缩小了很多。 // 再利用 lower_bound 和 upper_bound 代价小非常多 half = len >> 1; middle = first; advance(middle, half); if (*middle < value) { first = middle; ++first; len = len - half - 1; } else if (value < *middle) len = half; else { left = lower_bound(first, middle, value); advance(first, len); right = upper_bound(++middle, first, value); return pair<ForwardIterator, ForwardIterator>(left, right); } } return pair<ForwardIterator, ForwardIterator>(first, first); } // RandomAccessIterator 版本号 template <class RandomAccessIterator, class T, class Distance> pair<RandomAccessIterator, RandomAccessIterator> __equal_range(RandomAccessIterator first, RandomAccessIterator last, const T& value, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle, left, right; while (len > 0) { half = len >> 1; middle = first + half; if (*middle < value) { first = middle + 1; len = len - half - 1; } else if (value < *middle) len = half; else { left = lower_bound(first, middle, value); right = upper_bound(++middle, first + len, value); return pair<RandomAccessIterator, RandomAccessIterator>(left, right); } } return pair<RandomAccessIterator, RandomAccessIterator>(first, first); }


演示样例:
int main()
{
  int A[] = { 1, 2, 3, 3, 3, 5, 8 };
  const int N = sizeof(A) / sizeof(int);


  for (int i = 2; i <= 4; ++i) {
    pair<int*, int*> result = equal_range(A, A + N, i);


    cout << endl;
    cout << "Searching for " << i << endl;
    cout << "  First position where " << i << " could be inserted: "
         << result.first - A << endl;
    cout << "  Last position where " << i << " could be inserted: "
         << result.second - A << endl;
    if (result.first < A + N)
      cout << "  *result.first = " << *result.first << endl;
    if (result.second < A + N)
      cout << "  *result.second = " << *result.second << endl;
  }
}  
/*  
The output is:
Searching for 2
  First position where 2 could be inserted: 1
  Last position where 2 could be inserted: 2
  *result.first = 2
  *result.second = 3


Searching for 3
  First position where 3 could be inserted: 2
  Last position where 3 could be inserted: 5
  *result.first = 3
  *result.second = 5


Searching for 4
  First position where 4 could be inserted: 5
  Last position where 4 could be inserted: 5
  *result.first = 5
  *result.second = 5*/


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

标签:

原文地址:http://www.cnblogs.com/mengfanrong/p/5187087.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!