Effective_STL 学习笔记(四十五) 注意 count、find、binary_search、lower_bound、upper_bound 和 equal_range 的区别

如果区间有序,可以使用对数时间的算法,binary_search、lower_bound、upper_bound 和 equal_range 

如果迭代器没有划分一个有序区间,只能用线性时间的算法 count、count_if、find 和 find_if 

cout 回答: 是否存在这个值,如果有,那么存在几分拷贝?

find 回答: 是否存在,如果有,那么它在哪?

count 返回零或一个正数,所以把非零转换为 true 而把零转化为 false

1     if( count(lw.begin(), lw.end(), w) )  // 检查是否有w在lw中
2       . . .

使用 find 的算法可以在搜索到就停止,不必继续搜索

1   if( find( lw.begin(), lw.end(), w ) != lw.end() )
2     . . .    // 找到了
3   else
4     . . .    // 没找到

想获得区间中的第一个等于该值的对象,就得使用 find:

1   list<Widget>::iterator i = find( lw.begin(), lw.end(), w );
2   if( i != lw.end() )
3     . . .   // 找到了,i 指向第一个
4   else
5     . . .   // 没有找到

有序区间搜索算法是线性时间的 binary_search、lower_bound、upper_bound 和 equal_range 是对数时间的,从无序区间迁移到有序区间导致另一个迁移:从使用相等来判断两个值是否相同到使用等价来判断。

binary_searh 回答: 它在吗?它的回答只能是是或者不是

1   if( binary_search( lw.begin(), lw.end(), w ) )
2     . . .  // w 在 lw 中
3   else
4     . . .   // w 不在 lw 中 

如果要回答: 它在吗,如果是,那么在哪里? 你就需要 equal_range,但可能想要 lower_bound

lower_bound 回答: 它在吗?如果是,第一个拷贝在哪?如果不是,它将在哪里?

lower_bound 要检测返回值是否等于 end 迭代器,还要检测标识对象是都为找的值

1   vector<Widget>::iterator i = lower_bound( vw.begin(), vw.end(), w );
2   if( i != vw.end() && *i == w )    //  这有一个 bug
3     . . .        
4   else
5     . . . 

大多数情况能通过,bug 在于 *i == w 这是一个相等测试,而 lower_bound 用的是等价测试

equal_range 返回一对迭代器,第一个等于 lower_bound 返回的迭代器,第二个等于 upper_bound 返回的迭代器。因此,equal_range 返回了一对划分出了和你要搜索的值的等价的区间的迭代器。

 1   vector<Widget> vw;
 2   . . .
 3   sort( vw.begin(), vw.end() );
 4   typedef vector<Widget>::iterator VWIter;
 5   typedef pair<VWIter, VWIter> VWIterPair;
 6   VWIterPair p = equal_range( vw.begin(), vw.end(), w );
 7   if( p.first != p.second )
 8     . . .  // 找到了,p.first 指向第一个,p.second 指向第二个
 9   else
10     . . .  // 没找到 p.first 和 p.second 都指向搜索值的插入位置 

equal_range 返回的东西是两个迭代器,对他们作 distance 就等于区间中对象的数目,也就是等价于要寻找的值的对象。equal_range 不光完成了搜索有序区间的任务,而且完成了计数(distance())

1   cout<<"There are"<< distance(p.first, p.second) <<"elements in vw";

对于标准关联容器(set、multiset、map 和 multimap)使用它们成员函数代替同名算法,没有 binary_search 对应的成员函数,对于 set 或者 map 使用 count 的惯用法,对于 multiset 和 multimap 使用 find 比 count 好。

猜你喜欢

转载自www.cnblogs.com/kidycharon/p/10053466.html
今日推荐