查找信息:binary_search/lower_bound/upper_bound/equal_range/count/count_if/find/find_if
如果迭代器区间的数据是有序的:建议使用binary_search/lower_bound/upper_bound/equal_range(使用等价性搜索)
如果迭代器区间的数据是无序的:建议使用count/count_if/find/find_if(使用相等性搜索)
=================count和find==================
count回答的问题是:区间中是否存在某个特定的值,如果存在,有多少个拷贝
find回答的问题是:区间中是否存在某个特定的值,如果存在话,它在哪里
void CountVSFind()
{
//要求:问list中是否存在10
list<int> lInt;
int special = 10;
//dosomething
if (count(lInt.begin(), lInt.end(), special))
{
//if num>0
}
else
{
//if notfound
}
//The next is find
if (find(lInt.begin(), lInt.end(), special) != lInt.end())
{
//find
}
else
{
//notfound
}
//就我们要求来看,这两种都能实现要求的功能,但是就效率来看,find更好
//因为我们不在意几个,而是是否存在,并且find找到第一个之后就返回了
}
#include<iostream>
#include<list>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
template<typename Con>
void Print(Con v)
{
Con::iterator it = v.begin();
for (; it != v.end(); ++it)
{
cout << *it << endl;
}
}
void CountVSFind()
{
//要求:问list中是否存在10
list<int> lInt;
int special = 10;
//dosomething
if (count(lInt.begin(), lInt.end(), special))
{
//if num>0
}
else
{
//if notfound
}
//The next is find
if (find(lInt.begin(), lInt.end(), special) != lInt.end())
{
//find
}
else
{
//notfound
}
//就我们要求来看,这两种都能实现要求的功能,但是就效率来看,find更好
//因为我们不在意几个,而是是否存在,并且find找到第一个之后就返回了
}
//==========下边是排序区间使用搜索函数的示例=========================
void binarySearchFunction(vector<int> v,int num)
{
//注意binary_search的返回值是bool型,即只告诉你是否存在
sort(v.begin(), v.end());
if (binary_search(v.begin(), v.end(), num))
{
//找到
}
else
{
//没找到
}
}
void lowerBoundFUnction(vector<int> v, int num)
{
//lower_bound回答的问题是:这个值存在于区间中么?如果存在,她的第一份
//拷贝在哪里?如果不存在,它应该往哪里插入
sort(v.begin(), v.end());
vector<int>::iterator it = lower_bound(v.begin(), v.end(), num);
if (it != v.end() && *it != num)
{
//注意,不能仅仅使用end迭代器来测试lower_bound的返回值
//相反必须测试返回值所指向的对象,从而判断该对象是否是你想要找的值
//确保i指向一个对象,并且该对象有正确的值;这里是一个错误
//找到了该值,it指向第一个具有该值的对象
}
else
{
//没有找到
}
//注意,其实上边的代码是有问题的
//因为if()中的条件其实是相等测试,而我们需要的是等价测试
//有一种更容易的方法,就是使用equal_range,请接着看下边的代码
}
void equalRangeFunction(vector<int> v, int num)
{
//equal_range返回一对迭代器,第一个等于lower_bound返回的迭代
//器,第二个等于upper_bound返回的(也就是,等价于要搜索值区间的末迭代器的下一个)
sort(v.begin(), v.end());
typedef vector<int>::iterator intIter;
typedef pair<intIter, intIter> intPair;
intPair p = equal_range(v.begin(), v.end(), num);
if (p.first != p.second)
{
//如果equal_range返回的是非空区间,找到了特定的值,p.first指向的是
//第一个与num等价的对象,p.second指向的是最后一个与Num等价对象的下一个对象
}
else
{
//如果没有找到特定值,p.first和p.second都指向num的插入位置
}
//equal_range返回的迭代器之间的距离与这个区间中对象的数目是相等的。
//因此,下边的代码将显示与num等价的代码一共有多少个
cout << "There are" << distance(p.first, p.second)
<< "elements in v equal to num." << endl;
}
//下边的函数使lower_bound和upper_bound的用法举例
void LowerExample()
{
//现在假设vector<int>中是按照从小到大的顺序排列
vector<int> v;
for (int i = 0; i <=20; i++)
{
v.push_back(i);
}
//假设要删除那些>10的数字
v.erase(v.begin(), lower_bound(v.begin(), v.end(), 10));
Print<vector<int>>(v);
}
void UpperExample()
{
//现在假设vector<int>中是按照从小到大的顺序排列
vector<int> v;
for (int i = 0; i <= 20; i++)
{
v.push_back(i);
}
//假设要删除那些>=10的数字
v.erase(v.begin(), upper_bound(v.begin(), v.end(), 10));
Print<vector<int>>(v);
}
class person
{
public:
person(){};
const string& name() const{ return thisname; };
private:
string thisname;
};
struct PersonNameLess :
public binary_function<person, person, bool>{
bool operator()(const person& lhs, const person& rhs) const
{
return lhs.name() < rhs.name();
}
};
void ListUpperExample()
{
list<person> lp;
lp.sort(PersonNameLess());//按照从小到大的顺序进行排列
person newPerson;
//dosomethind
//将newPerson插入到lp中排在最后一个newPerson之前或者与newPerson等价的对象之后
lp.insert(upper_bound(lp.begin(), lp.end(), newPerson, PersonNameLess()),newPerson);
//这段代码方便而且正确,但是并不意味着在list中使用upper_bound来找到插入的位置只需要
//对数的时间,不是这样的,在34条中解释过原因。因为我们操作了一个list,所以它只执行了对数次数
//的比较次数,但是查找仍需要线性的时间。
}
//但是对于标准的关联容器,情形就不同了,它们自带的成员函数比STL算法更加好
void GuanlianContainExample()
{
//凡是在前边的讨论中建议选择的算法count/find/equal_range/lower_bound/upper_bound
//的地方,针对关联容器,只需要选择同名的成员函数即可。只有binary_search是个例外,因为
//关联容器中不存在同名的函数
set<int> si;
//doSomethind,在set中插入数据
int num = 10;//待查找的数据
if (si.count(num))
{
//存在与num等价的值
}
else
{
//不存在与num等价的值
}
//要在multiset和multimap中测试一个值是否存在,用count就好了
//但是要是统计某个值的个数,用count就行
}
int main()
{
UpperExample();
}