zoukankan      html  css  js  c++  java
  • STL 源代码剖析 算法 stl_algo.h -- equal_range

    本文为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*/


  • 相关阅读:
    定时器中断彩灯控制程序
    单片机C51 8位流水灯
    十进制转换2-9进制转换
    加减乘除+菜单实现
    文件 I/O缓冲流
    文件 I/O字符流
    spring配置c3p0连接池
    javax.swing.Timer的与Lambda的使用
    代码简化之道--接口之从传统实现到Lambda表达式实现
    Java核心技术第六章--内部类
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5187087.html
Copyright © 2011-2022 走看看