这是二分查找(binary search)的一种版本,试图在已排序的[first,last)中寻找元素value:
如果[first,last)具有与value相等的元素(s),便返回一个迭代器,指向其中第一个元素;
如果没有这样的元素存在,便返回“假设这样的元素存在时应该出现的位置”,也就是说,它返回一个迭代器,指向第一个“不小于value”的元素;
如果value大于{first,last)内的任何一个元素,则返回last。
STL源码:
template <class ForwardIterator,class T> inline ForwardIterator lower_bound(ForwardIterator first,ForwardIterator last,const T& value) { return _lower_bound(first,last,value,distance_type(first),iterator_category(first)); } //forward_iterator版本 template <class ForwardIterator,class T,class Distance> ForwardIterator _lower_bound(ForwardIteartor first,ForwardIterator last,const T& value,Distance*,forward_iterator_tag) { Distance len=0; distacne(first,last,len); Diatacne half; ForwardIterator middle; while(len>0) { half=len>>1; //除以2 middle=first; //迭代器必须有初始值,才能应用advance advance(middle,half); //middle+=half; 支持所有容器迭代器的操作 if(*middle<value) { first=middle; ++first; len=len-half-1; } else len=half; } return first; }
//random_access_iterator版本 template <class RandomAccessIterator,class T,class Distance> RandomAccessIterator _lower_bound(RandomAccessIterator first,RandomAccessIterator last,const T& value,Distance*,random_access_iterator_tag) { Distance len=last-first; Diatacne half; RandomAccessIterator middle; while(len>0) { half=len>>1; //除以2 middle=first+half; if(*middle<value) { first=middle+1; len=len-half-1; } else len=half; } return first; }
代码示例:
//测试lower_bound #include<iostream> #include<algorithm> #include<iterator> #include<vector> #include<set> using namespace std; int main() { //vector 测试---序列式容器 vector<int> coll; vector<int>::iterator pos; coll.push_back(1); coll.push_back(1); coll.push_back(3); coll.push_back(3); coll.push_back(3); coll.push_back(3); coll.push_back(5); coll.push_back(7); coll.push_back(9); copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));//1 1 3 3 3 3 5 7 9 cout<<endl; pos=lower_bound(coll.begin(),coll.end(),2);//如果找不到与value值相同的元素,则返回第一个“不小于value”的元素的位置 //即返回的是第一个元素'3'的位置 cout<<"lower_bound 2: "; copy(pos,coll.end(),ostream_iterator<int>(cout," ")); cout<<endl; pos=lower_bound(coll.begin(),coll.end(),3);//如果找到与value值相同的元素,则返回第一个该元素值的位置 //即返回的是第一个元素'3'的位置 cout<<"lower_bound 3: "; copy(pos,coll.end(),ostream_iterator<int>(cout," ")); cout<<endl; //multiset测试---关联式容器 multiset<int> coll1; multiset<int>::iterator pos1; coll1.insert(1); coll1.insert(3); coll1.insert(5); coll1.insert(7); coll1.insert(7); coll1.insert(7); coll1.insert(9); coll1.insert(9); copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); cout<<endl; pos1=lower_bound(coll1.begin(),coll1.end(),7);//如果找到与value值相同的元素,则返回第一个该元素值的位置 //即返回第一个元素'7'的位置 cout<<"lower_bound 7: "; copy(pos1,coll1.end(),ostream_iterator<int>(cout," ")); cout<<endl; pos1=lower_bound(coll1.begin(),coll1.end(),8);//如果找不到与value值相同的元素,则返回第一个“不小于value”的元素的位置 //即返回的是第一个元素'9'的位置 cout<<"lower_bound 8: "; copy(pos1,coll1.end(),ostream_iterator<int>(cout," ")); cout<<endl; system("pause"); return 0; }
STL源码:
template <class ForwardIterator,class T> inline ForwardIterator upper_bound(ForwardIterator first,ForwardIterator last,const T& value) { return _upper_bound(first,last,value,distance_type(first),iterator_category(first)); } //forward_iterator版本 template <class ForwardIterator,class T,class Distance> ForwardIterator _upper_bound(ForwardIteartor first,ForwardIterator last,const T& value,Distance*,forward_iterator_tag) { Distance len=0; distacne(first,last,len); Diatacne half; ForwardIterator middle; while(len>0) { half=len>>1; //除以2 middle=first; //迭代器必须有初始值,才能应用advance advance(middle,half); //middle+=half; 支持所有容器迭代器的操作 if(value<*middle) { len=half; } else { first=middle; ++first; len=len-half-1; } } return first; }
//random_access_iterator版本 template <class RandomAccessIterator,class T,class Distance> RandomAccessIterator _upper_bound(RandomAccessIterator first,RandomAccessIterator last,const T& value,Distance*,random_access_iterator_tag) { Distance len=last-first; Diatacne half; RandomAccessIterator middle; while(len>0) { half=len>>1; //除以2 middle=first+half; if(value<*middle) { len=half; } else { first=middle+1; len=len-half-1; } } return first; }
//测试upper_bound #include<iostream> #include<algorithm> #include<iterator> #include<vector> #include<set> using namespace std; int main() { //vector 测试---序列式容器 vector<int> coll; vector<int>::iterator pos; coll.push_back(1); coll.push_back(1); coll.push_back(3); coll.push_back(3); coll.push_back(3); coll.push_back(3); coll.push_back(5); coll.push_back(7); coll.push_back(9); copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));//1 1 3 3 3 3 5 7 9 cout<<endl; pos=upper_bound(coll.begin(),coll.end(),2);//如果找不到与value值相同的元素,则返回第一个“不小于value”的元素的位置 //即返回的是第一个元素'3'的位置 cout<<"lower_bound 2: "; copy(pos,coll.end(),ostream_iterator<int>(cout," ")); cout<<endl; pos=upper_bound(coll.begin(),coll.end(),3);//如果找到与value值相同的元素,则返回第一个该元素值的位置 //即返回的是第一个元素'3'的位置 cout<<"lower_bound 3: "; copy(pos,coll.end(),ostream_iterator<int>(cout," ")); cout<<endl; //multiset测试---关联式容器 multiset<int> coll1; multiset<int>::iterator pos1; coll1.insert(1); coll1.insert(3); coll1.insert(5); coll1.insert(7); coll1.insert(7); coll1.insert(7); coll1.insert(9); coll1.insert(9); copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); cout<<endl; pos1=upper_bound(coll1.begin(),coll1.end(),7);//如果找到与value值相同的元素,则返回第一个该元素值的位置 //即返回第一个元素'7'的位置 cout<<"lower_bound 7: "; copy(pos1,coll1.end(),ostream_iterator<int>(cout," ")); cout<<endl; pos1=upper_bound(coll1.begin(),coll1.end(),8);//如果找不到与value值相同的元素,则返回第一个“不小于value”的元素的位置 //即返回的是第一个元素'9'的位置 cout<<"lower_bound 8: "; copy(pos1,coll1.end(),ostream_iterator<int>(cout," ")); cout<<endl; system("pause"); return 0; }
STL源码:
template<class ForwardIterator,class T> bool binary_search(ForwardIterator first,ForwardIterator last,const T& value) { ForwardIterator i=lower_bound(first,last,value); return i!=last && !(value<*i); }
代码示例:
#include<iostream> #include<algorithm> #include<vector> using namespace std; int main() { vector<int> coll; vector<int>::iterator pos; coll.push_back(1); coll.push_back(1); coll.push_back(3); coll.push_back(3); coll.push_back(3); coll.push_back(3); coll.push_back(5); coll.push_back(7); coll.push_back(9); if(binary_search(coll.begin(),coll.end(),2)) { cout<<"value Found!"<<endl; } else { cout<<"value Not Found!"<<endl; } system("pause"); return 0; }