您的位置:首页 > 其它

泛型算法系列5:lower_bound()&&upper_bound()

2009-08-07 17:02 316 查看
#include <algorithm>
#include <vector>
#include <iostream>
#include <functional>
#include <assert.h>

using namespace std;

template <class Type>
void print_elements(Type elem)
{
cout << elem << ",";
}

void (*pfi)(int) = print_elements;

int main()
{
int a[] = {29,23,20,22,17,15,26,51,19,12,35,40};
vector<int> vec(a, a + 12);

sort(a, a + 12);
cout << "after sort." << endl;
for_each(a, a + 12, pfi);
//when use upper, we got iter which point to the data after key
int *iter = upper_bound(a, a + 12, 19);
assert( *iter == 20 );
//when use lower, when we find the same value,we got iter which the data equal to key
iter = lower_bound(a, a + 12, 19);
assert( *iter == 19 );
//in this case the answer is the same
int* iter_new = upper_bound(a, a + 12, 18);
//int* iter_new = lower_bound(a, a + 12, 18);
assert( *iter_new == 19 );

cout << "/n#####################################/n" << endl;
sort(vec.begin(), vec.end(), greater<int>());
for_each(vec.begin(), vec.end(), pfi);
vector<int>::iterator iter_vec;

//when use upper, we got iter which point to the data after key
iter_vec = upper_bound(vec.begin(), vec.end(),
27, greater<int>());
assert( *iter_vec == 26 );
//when use lower, we got iter which point to the data before key
iter_vec = lower_bound(vec.begin(), vec.end(),
27, greater<int>());
assert( *iter_vec == 26 );

cout << "/n#####################################/n" << endl;
vec.insert(iter_vec, 27);
for_each(vec.begin(), vec.end(), pfi);
return 0;
}

/************************************************************************/
/**/
template<class _FwdIt, class _Ty, class _Diff> inline
_FwdIt _Upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *)
{	// find first element that _Val is before, using operator<
_Distance(_First, _Last, _Count);
for (; 0 < _Count; )
{	// divide and conquer, find half that contains answer
_Diff _Count2 = _Count / 2;
_FwdIt _Mid = _First;
std::advance(_Mid, _Count2);
_DEBUG_ORDER_SINGLE(_Mid, _Last, false);

if (!_DEBUG_LT(_Val, *_Mid))
_First = ++_Mid, _Count -= _Count2 + 1;
else
_Count = _Count2;
}
return (_First);
}

/************************************************************************/

/************************************************************************/
/**/
template<class _FwdIt,
class _Ty,
class _Diff> inline
_FwdIt _Lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *)
{	// find first element not before _Val, using operator<
_DEBUG_ORDER_SINGLE(_First, _Last, true);
_Diff _Count = 0;
_Distance(_First, _Last, _Count);

for (; 0 < _Count; )
{	// divide and conquer, find half that contains answer
_Diff _Count2 = _Count / 2;
_FwdIt _Mid = _First;
std::advance(_Mid, _Count2);
_DEBUG_ORDER_SINGLE(_Mid, _Last, false);

if (_DEBUG_LT(*_Mid, _Val))
_First = ++_Mid, _Count -= _Count2 + 1;
else
_Count = _Count2;
}
return (_First);
}

/************************************************************************/

/************************************************************************/
/*                                                                      */
template<class _InIt, class _Diff> inline
void __CLRCALL_OR_CDECL _Distance2(_InIt _First, _InIt _Last, _Diff& _Off,
input_iterator_tag)
{	// add to _Off distance between input iterators
for (; _First != _Last; ++_First)
++_Off;
}
/************************************************************************/


注释:

binary_search:判断是否存在某个对象
lower_bound: 返回>=对象的第一个位置,lower_bound(2)=3, lower_bound(3)=3
目标对象存在即为目标对象的位置,不存在则为后一个位置.
upper_bound: 返回>对象的第一个位置, upper_bound(2)=3,upper_bound(3)=4
无论是否存在都为后一个位置.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: