您的位置:首页 > 编程语言 > C语言/C++

本科教育忽略的黄金C++<7> 无序容器

2016-02-26 20:16 351 查看
新标准定义了4个无序关联容器,这些容器不是使用比较运算符来组织元素,而是使用哈希函数和关键字类型的==运算符。在关键字类型的元素没有明显的序关系情况下,无序容器是非常有用的。

哈希函数百科介绍

1、使用无序容器

无序容器提供了与有序容器相同的操作。这意味着我们在map和set操作也能用于unordered_map和unordered _set。类似的,无需容器也有允许重复关键字的版本。

示例程序:

仍然是前面文章所提到的查找单词出现次数的程序:

unordered_map<string,size_t>word_count;
string word;
while(cin>>word)
++word_count[word];
for(const auto &w: word_count)
{
cout<<w.first<<" occurs "<<w.second
<<((w.second>1)?" times":" time")<<endl;
}


和原程序唯一的一个区别是word_count的类型。注意,对于相同的单词,我们得到相同的计数结果,但是单词不会以字典序排序。

2、管理桶

无序容器在存储上组织为一组桶,每个桶保存零个或者多个元素。无序容器使用一个哈希函数将元素映射到桶。为了访问一个元素,容器首先计算元素的哈希值,它指出应该搜索哪个桶。容器将具有一个特定哈希值的所有元素都保存在相同的桶中。如果容器允许重复关键字,所有具有相同关键字的元素也会在同一个桶中。因此,无序容器的性能依赖于哈希函数的质量和桶的数量和大小。

对于相同的参数,哈希函数必须总是产生相同的结果。理想状态下,哈希函数还能将每个特定的值映射到唯一的桶中。但是,将不同关键字的元素映射到相同的桶中也是允许的。当一个桶保存多个元素的时候,需要顺序搜索这些元素来进行查找。

查询容器的状态以及在必要时刻强制容器进行重组:

//桶接口
c.bucket_count():正在使用的桶的数目。
c.max_bucket_count():容器能够容纳的最多的桶的数量。
c.bucket_size(n):第n个桶中有多少个元素。
c.bucket(k):关键字为k的元素在哪个桶中。

//桶迭代
local_iterator:可以用来访问桶中元素的迭代器类型。
const_local_iterator:桶迭代器的const版本。
c.begin(n),c.end(n):桶n的首元素迭代器和尾后迭代器。
c.cbegin(n),c.cend(n):和上两个个函数类似。返回const_local_iterator

//哈希策略
c.load_factor():每个通的平均元素数量,返回float值。

c.max_load_factor():c试图维护的平均桶大小。返回float值。c会在需要时添加新的桶,从而使得load_factor<=max_load_factor

c.rehash(n):重组存储,使得bucket_count>=n

c.reserve(n):重组存储,使得c可以保存n个元素,且不必rehash。


3、无序容器对关键字类型的要求

默认情况下,无序容器使用关键字类型的==运算符来比较元素,还是用一个hash< key_type >类型的对象来生成每个元素的哈希值。标准库为内置类型(包括指针)提供了hash模板。

我们不能直接定义关键字类型为自定义类型的无序容器。和容器不同,不能直接使用哈希模板,而是必须提供我们自己的hash模板版本。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 无序容器