本科教育忽略的黄金C++<7> 无序容器
2016-02-26 20:16
351 查看
新标准定义了4个无序关联容器,这些容器不是使用比较运算符来组织元素,而是使用哈希函数和关键字类型的==运算符。在关键字类型的元素没有明显的序关系情况下,无序容器是非常有用的。
哈希函数百科介绍
1、使用无序容器
无序容器提供了与有序容器相同的操作。这意味着我们在map和set操作也能用于unordered_map和unordered _set。类似的,无需容器也有允许重复关键字的版本。
示例程序:
仍然是前面文章所提到的查找单词出现次数的程序:
和原程序唯一的一个区别是word_count的类型。注意,对于相同的单词,我们得到相同的计数结果,但是单词不会以字典序排序。
2、管理桶
无序容器在存储上组织为一组桶,每个桶保存零个或者多个元素。无序容器使用一个哈希函数将元素映射到桶。为了访问一个元素,容器首先计算元素的哈希值,它指出应该搜索哪个桶。容器将具有一个特定哈希值的所有元素都保存在相同的桶中。如果容器允许重复关键字,所有具有相同关键字的元素也会在同一个桶中。因此,无序容器的性能依赖于哈希函数的质量和桶的数量和大小。
对于相同的参数,哈希函数必须总是产生相同的结果。理想状态下,哈希函数还能将每个特定的值映射到唯一的桶中。但是,将不同关键字的元素映射到相同的桶中也是允许的。当一个桶保存多个元素的时候,需要顺序搜索这些元素来进行查找。
查询容器的状态以及在必要时刻强制容器进行重组:
3、无序容器对关键字类型的要求
默认情况下,无序容器使用关键字类型的==运算符来比较元素,还是用一个hash< key_type >类型的对象来生成每个元素的哈希值。标准库为内置类型(包括指针)提供了hash模板。
我们不能直接定义关键字类型为自定义类型的无序容器。和容器不同,不能直接使用哈希模板,而是必须提供我们自己的hash模板版本。
哈希函数百科介绍
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++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性