C++ STL: lower_bound 和 upper_bound

接口声明

以下有两个不同的版本

lower_bound

  • template <class ForwardIterator, class T>
      ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                                   const T& val);
    
  • template <class ForwardIterator, class T, class Compare>
      ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                                   const T& val, Compare comp);
    

upper_bound

  • template <class ForwardIterator, class T>
      ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,
                                   const T& val);
    
  • template <class ForwardIterator, class T, class Compare>
      ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,
                                   const T& val, Compare comp);
    

两个接口都是返回一个迭代器,且改迭代器指向一个非递减序列[first,last)内部 的一个元素地址,后续通过该迭代器继续访问剩余元素。

两个接口的主要区别是:

lower_bound 指向的是第一个大于等于val的位置

upper_bound 指向的是第一个大于val的位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6B3E9GCI-1592484277761)(/Users/zhanghuigui/Library/Application Support/typora-user-images/image-20200618111744296.png)]

接口源码实现

Lower_bound

//  function : lower_bound
/// @brief Returns an iterator pointing to the first element in the range
///        [first, last) that is not less than (i.e. greater or equal to) val.
/// @param [in] last : iterator to the last element of the range
/// @param [in] val : value to find
/// @param [in] comp : object for to compare two value_t objects
/// @return iterator to the element found
//-----------------------------------------------------------------------------
// 返回大于等于val的数据
template<class Iter_t, class Filter = filter_pass<value_iter<Iter_t> >,
                class Compare = std::less<typename Filter::key> >
inline Iter_t lower_bound(Iter_t first, Iter_t last,
                          const typename Filter::key &val,
                          const Compare & comp = Compare(), 
                          Filter flt = Filter())
{
    assert((last - first) >= 0);
    if (last == first) return last;
    Iter_t itaux = internal_find_first(first, last, val, comp, flt);
    return (itaux == (last - 1) and comp(flt(*itaux), val)) ? last : itaux;
};

//-----------------------------------------------------------------------------
//  function : internal_find_first
/// @brief find if a value exist in the range [first, last).
///        Always return as valid iterator in the range [first, last-1]
///        If exist return the iterator to the first occurrence. If don't exist
///        return the first greater than val.
///        If val is greater than the *(last-1), return (last-1)
///        If val is lower than  (*first), return  first
//
/// @param [in] first : iterator to the first element of the range
/// @param [in] last : iterator to the last element of the range
/// @param [in] val : value to find
/// @param [in] comp : object for to compare two value_t objects
/// @return iterator to the element found,
//-----------------------------------------------------------------------------
// 使用internal function进行二分查找
template <class Iter_t, class Filter = filter_pass<value_iter<Iter_t> >,
          class Compare = std::less<typename Filter::key> >
inline Iter_t internal_find_first(Iter_t first, Iter_t last,
                                  const typename Filter::key &val,
                                  const Compare & comp = Compare(), 
                                  Filter flt = Filter())
{
    Iter_t LI = first, LS = last - 1, it_out = first;
    while (LI != LS)
    {
        it_out = LI + ((LS - LI) >> 1);
        if (comp(flt(*it_out), val))
            LI = it_out + 1;
        else LS = it_out;
    };
    return LS;
};

Upper bound

//  function :upper_bound
/// @brief return the first element greather than val.If don't exist
///        return last
//
/// @param [in] first : iterator to the first element of the range
/// @param [in] last : iterator to the last element of the range
/// @param [in] val : value to find
/// @param [in] comp : object for to compare two value_t objects
/// @return iterator to the element found
/// @remarks
//-----------------------------------------------------------------------------
//返回大于val的数据
template<class Iter_t, class Filter = filter_pass<value_iter<Iter_t> >,
                class Compare = std::less<typename Filter::key> >
inline Iter_t upper_bound(Iter_t first, Iter_t last,
                          const typename Filter::key &val,
                          const Compare & comp = Compare(), 
                          Filter flt = Filter())
{
    assert((last - first) >= 0);
    if (last == first) return last;
    Iter_t itaux = internal_find_last(first, last, val, comp, flt);
    return (itaux == first and comp(val, flt(*itaux))) ? itaux : itaux + 1;
}

//  function : internal_find_last
/// @brief find if a value exist in the range [first, last).
///        Always return as valid iterator in the range [first, last-1]
///        If exist return the iterator to the last occurrence.
///        If don't exist return the first lower than val.
///        If val is greater than *(last-1) return (last-1).
///        If is lower than the first, return first
//
/// @param [in] first : iterator to the first element of the range
/// @param [in] last : iterator to the last element of the range
/// @param [in] val : value to find
/// @param [in] comp : object for to compare two value_t objects
/// @return iterator to the element found, if not found return last

//-----------------------------------------------------------------------------
template<class Iter_t, class Filter = filter_pass<value_iter<Iter_t> >,
                class Compare = std::less<typename Filter::key> >
inline Iter_t internal_find_last(Iter_t first, Iter_t last,
                                 const typename Filter::key &val,
                                 const Compare & comp = Compare(), Filter flt =
                                                 Filter())
{
    Iter_t LI = first, LS = last - 1, it_out = first;
    while (LI != LS)
    {
        it_out = LI + ((LS - LI + 1) >> 1);
        if (comp(val, flt(*it_out))) LS = it_out - 1;
        else                         LI = it_out;
    };
    return LS;
};

应用

// lower_bound/upper_bound example
#include      // std::cout
#include     // std::lower_bound, std::upper_bound, std::sort
#include        // std::vector

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};
  std::vector<int> v(myints,myints+8);           // 10 20 30 30 20 10 10 20

  std::sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30

  std::vector<int>::iterator low,up;
  low=std::lower_bound (v.begin(), v.end(), 20); //          ^
  up= std::upper_bound (v.begin(), v.end(), 20); //                   ^

  std::cout << "lower_bound at position " << (low- v.begin()) << '\n';
  std::cout << "upper_bound at position " << (up - v.begin()) << '\n';

  return 0;
}

输出如下

lower_bound at position 3  # 第一个大于等于20的位置
upper_bound at position 6  # 第一个大于20的位置

你可能感兴趣的:(#,编程语言:C++,编程语言)