- Rule45:注意count,find,binary_search,lower_bound,upper_bound,equal_range的区别
count,find用于一个无序的容器集合内。
count返回是否存在这个值,如果有,那么有多少个?
find则用于考虑“是否存在这个值,如果有,那么第一个在哪儿?”找到后立即会返回。
所有,两个的方法的用处不一样,find的效率会高于count,因为它是找到后就立即返回。
从无序区间迁移到有序区间导致了另一个迁移,从使用相等来判断两个值是否相同到使用等价来判断。count和find都是用相等来搜索,而binary_search,lower_bound,upper_bound,equal_range则是用等价。
要测试在一个有序区间是否存在一个值,使用binary_search,binary_search只返回一个bool:这个值是否找到。
如果你需要在一个有序区间找到那个元素的位置,你需要equal_range或者lower_bound。
当你用lower_bound来寻找一个值的时候,它返回一个迭代器,这个迭代器指向这个值的第一个拷贝或者是可以插入这个值的位置。因此,lower_bound适用于这种情况“他在吗,如果是,第一个拷贝在哪儿?如果不在,那么他将要在哪儿”。对于lower_bound的返回值,你需要进行检测,不能只是检测返回值是否等于end迭代器,还必须检测这个迭代器的值是否是你需要的值。就像这样子:
vector<Widget>::iterator it = lower_bound(vw.begin(),vw.end(),w);
if(it!=vw.end()&&*it==w)
{
//找到了
}
else
//没找到
大部分情况这是行得通的,但不是真的完全相同。这是一样相等测试,但是lower_bound搜索用的是等价。
有一个更简单的方法,使用equal_range。equal_range返回一对迭代器,第一个等于lower_bound返回的迭代器,第二个等于upper_bound返回的。对于equal_range的返回值,如果这两个迭代器相同,就意味着对象的区间是空的;这个只没有找到。这个结果是用equal_range来回答“它在吗?”这个问题的答案。使用distance处理equal_range返回的两个迭代器pair,能够计算出有多少个相同的元素。
代码你可以这么用:
vector<int> wints;
wints.reserve(10);
wints.push_back(10);
wints.push_back(20);
wints.push_back(50);
wints.push_back(60);
wints.push_back(30);
wints.push_back(40);
wints.push_back(90);
wints.push_back(80);
wints.push_back(70);
wints.push_back(100);
sort(wints.begin(),wints.end(),greater<int>());
//wints = [10](100,90,80,70,60,50,40,30,20,10)
vector<int>::iterator it = lower_bound(wints.begin(),wints.end(),11,greater<int>());
if (it!=wints.end()&&*it==20)
{
int a = *it;
a = 10;
}
typedef vector<int>::iterator VIntIter;
typedef pair<VIntIter,VIntIter> VIntIterPair;
VIntIterPair p = equal_range(wints.begin(),wints.end(),20,greater<int>());
if (p.first!=p.second)
{
//找到了
}
distance(p.first,p.second);//找到的元素个数