掌握C++ STL容器搜索技巧:实现高效和准确的数据访问
有三个原因:
-
它更快:排序的容器,所有方法都受益于排序集合的快速对数搜索。此外,
std::string方法实现了最优算法。 -
它更自然:
std::map和std::multimap方法可以直接搜索键,而不像算法必须查找std::pair<key,Value>,因为它们的迭代器可以直接指向。 -
它在某些情况下更正确:在排序容器(如
map和set)中,所有方法都使用等价而不是相等,而某些算法(如std::count和std::find使用相等)则不是这样。
现在究如何把它应用到 STL 提供的各种容器来深入了解更多细节。
std::vector, std::deque, std::list 这些容器没有公开任何与搜索相关的方法,只能通过算法来搜索。
二、std::map/multimap, std::set/multiset
这些容器有5个类方法,它们跟一些算法共享它们的名称:count, find, equal_range, lower_bound和upper_bound。
这些方法和算法的比较:
|
容器方法 |
比算法更正确? |
比算法还快? |
比算法更自然? |
|---|---|---|---|
|
count |
是 |
是 |
是 |
|
find |
是 |
是 |
是 |
|
equal_range |
相同 |
是 |
是 |
|
lower_bound |
相同 |
是 |
是 |
|
upper_bound |
相同 |
是 |
是 |
-
更好的正确性是因为使用了等效而不是相等。
-
更好的性能来自于为序列容器对元素进行排序这一事实。对于关联容器来说,这是因为它们的迭代器不是随机访问的,所以算法不能通过直接跳过所需的元素来执行分割(它们必须从头开始并向上移动到它们的位置),而容器的内部没有这种约束。
-
它们对于映射来说更自然,因为传递给各种方法的参数是一个键,而不是
std::pair<key, Value>。
注意,没有跟std::binary_search等价的容器方法。检查容器中是否存在一个键:
-
对于
std::map和std::set:比较find的结果与end迭代器的结果。或者使用count方法。count作为方法不会引起任何性能问题,因为,像find一样,它在第一个与搜索的键相等的键处停止(因为根据std::map和std::set的定义,只能有一个键与搜索的键相等)。 -
对于
std::multimap和std::multiset:因为count不会在第一个与搜索的键相等的键处停止,所以find在这里比count有优势。
在std::multimap或std::multiset中,find方法返回与搜索值相等的任何元素,而不一定是第一个元素。如果确实需要第一个元素,可以使用equal_range,因为它具有简单的接口;或者,如果觉得equal_range太慢(因为它显示了整个范围),而只是需要第一个元素,那么可以使用lower_bound。但是,lower_bound同样也有它的缺点,也必须付出代价。
三、std::string
string实际上有24个搜索方法。分成6组,每组有4个重载。对于所有组,4个重载的形式为:
-
搜索由std::string给出的字符串。
-
搜索由char*和size给出的字符串。
-
搜索由char*给出的字符串(止于null字符)。
-
搜索一个字符。
并且所有4个重载都以搜索字符串中的起始位置作为参数,默认值为0(从字符串的开头开始搜索)。
更多推荐
所有评论(0)