首页 > C++ STL: lower_bound 和 upper_bound

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::vectorint 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 20std::sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30std::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()) << '
';std::cout << "upper_bound at position " << (up - v.begin()) << '
';return 0;
}

输出如下

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

更多相关:

  • 上篇笔记中梳理了一把 resolver 和 balancer,这里顺着前面的流程走一遍入口的 ClientConn 对象。ClientConn// ClientConn represents a virtual connection to a conceptual endpoint, to // perform RPCs. // //...

  • 我的实验是基于PSPNet模型实现二维图像的语义分割,下面的代码直接从得到的h5文件开始往下做。。。 也不知道是自己的检索能力出现了问题还是咋回事,搜遍全网都没有可以直接拿来用的语义分割代码,东拼西凑,算是搞成功了。 实验平台:Windows、VS2015、Tensorflow1.8 api、Python3.6 具体的流程为:...

  • Path Tracing 懒得翻译了,相信搞图形学的人都能看得懂,2333 Path Tracing is a rendering algorithm similar to ray tracing in which rays are cast from a virtual camera and traced through a s...

  • configure_file( [COPYONLY] [ESCAPE_QUOTES] [@ONLY][NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ]) 我遇到的是 configure_file(config/config.in ${CMAKE_SOURCE_DIR}/...

  •     直接复制以下代码创建一个名为settings.xml的文件,放到C:UsersAdministrator.m2下即可