C++ unordered_map
2016-07-27 09:08
477 查看
unordered_map的定义
template < class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, class Alloc = allocator< pair<const Key,T> >> class unordered_map;
模版参数说明:
Key
主键的类型。
在类模板内部,使用其别名为 key_type 的成员类型。
T
被映射的值的类型。
在类模板内部,使用其别名为 mapped_type 的成员类型。
Hash
一元谓词,以一个 Key 类型的对象为参数,返回一个基于该对象的 size_t 类型的唯一值。可以是函数指针(Function pointer)类型或函数对象(Function object)类型。在类模板内部,使用其别名为 hasher 的成员类型。
Pred
二元谓词,以两个 Key 类型的对象为参数,返回一个 bool 值,如果第一个参数等价于第二个参数,该 bool 值为 true,否则为 false。默认为 std::equal_to.可以是函数指针类型(Function pointer)类型或函数对象(Function object)类型.在类模板内部,使用其别名为 key_equal 的成员类型。
Alloc
容器内部用来管理内存分配及释放的内存分配器的类型。这个参数是可选的,它的默认值是 std::allocator,这个是一个最简单的非值依赖的(Value-independent)内存分配器。在类模板内部,使用其别名为 allocator_type 的成员类型。
特点
unordered_map是一个关联容器,存储key,value.其中元素并没有特别的次序关系特点:
1. 关联容器中的元素是通过主键(Key)而不是它们在容器中的绝对位置来引用的。
2. 无序(Unordered)无序容器通过 hash 表来组织它们的元素,允许通过主键快速地访问元素。
3. 映射(Map)每个元素为一个值(Mapped value)绑定一个键(Key):以主键来标志主要内容等于被映射值的元素。
4. 键唯一(Unique keys)容器中不存在两个元素有相同的主键。
5. 能够感知内存分配器的(Allocator-aware)容器使用一个内存分配器对象来动态地处理它的存储需求。
在 unordered_map 内部,元素不会按任何顺序排序,而是通过主键的 hash 值将元素分组放置到
各个槽(Bucket,也可译成“桶”)中,这样就能通过主键快速地访问各个对应的元素
(平均耗时为一个常量,即时间复杂度为 O(1))。
成员函数
=================迭代器=========================begin 返回指向容器起始位置的迭代器(iterator)
end 返回指向容器末尾位置的迭代器
cbegin 返回指向容器起始位置的常迭代器(const_iterator)
cend 返回指向容器末尾位置的常迭代器
=================Capacity================
size 返回有效元素个数
max_size 返回 unordered_map 支持的最大元素个数
empty 判断是否为空
=================元素访问=================
operator[] 访问元素
at 访问元素
=================元素修改=================
insert 插入元素
erase 删除元素
swap 交换内容
clear 清空内容
emplace 构造及插入一个元素
emplace_hint 按提示构造及插入一个元素
================操作=========================
find 通过给定主键查找元素
count 返回匹配给定主键的元素的个数
equal_range 返回值匹配给定搜索值的元素组成的范围
================Buckets======================
bucket_count 返回槽(Bucket)数
max_bucket_count 返回最大槽数
bucket_size 返回槽大小
bucket 返回元素所在槽的序号
load_factor 返回载入因子,即一个元素槽(Bucket)的最大元素数
max_load_factor 返回或设置最大载入因子
rehash 设置槽数
reserve 请求改变容器容量
测试
#include <unordered_map> #include <iostream> #include <string> using namespace std; void PrintIntDoubleUnOrderedMap(unordered_map<int, double>& m, char* pre) { unordered_map<int, double>::iterator iter; cout << pre; for (iter = m.begin(); iter != m.end(); ++iter) cout << "(" << iter->first << ", " << iter->second << ")" << " "; cout << endl; } void UnOrderedMapExp1() { unordered_map<int, double> m; //没有key,就自动创建 m[0] = 1.11; //普通插入,使用类型转换 m.insert(unordered_map<int, double>::value_type(1, 2.22)); //带暗示的插入,pair<int, double>就相当于上面的unordered_map<int ,double> m.insert(m.end(), pair<int, double>(2, 3.33)); PrintIntDoubleUnOrderedMap(m, "插入元素之前的m:"); //插入一个范围 unordered_map<int, double> m2; m2.insert(unordered_map<int, double>::value_type(3, 4.44)); m2.insert(unordered_map<int, double>::value_type(4, 5.44)); m2.insert(unordered_map<int, double>::value_type(5, 6.44)); m.insert(m2.begin(), m2.end()); m.emplace(6, 5.55); m.emplace_hint(m.end(), 7, 3.09); m.at(5) = 3.333333; PrintIntDoubleUnOrderedMap(m, "插入元素之后m:"); unordered_map<int, double>::iterator iter; iter = m.find(4); if (iter != m.end()) { cout << "m.find(4): "; cout << "(" << iter->first << ", " << iter->second << ")" << endl; } if (iter != m.end()) { m.erase(iter); } PrintIntDoubleUnOrderedMap(m, "删除主键为4的元素之后m:"); //遍历删除 for (iter = m.begin(); iter != m.end(); ++iter) { if (iter->first == 2) { m.erase(iter); break; } } //内部数据 cout << "bucket_count:" << m.bucket_count() << endl; cout << "max_bucket_count:" << m.max_bucket_count() << endl; cout << "bucket_size:" << m.bucket_size(0) << endl; std::cout << "load_factor:" << m.load_factor() << std::endl; std::cout << "max_load_factor:" << m.max_load_factor() << std::endl; PrintIntDoubleUnOrderedMap(m, "删除主键为2的元素后的foo1:"); m.clear(); PrintIntDoubleUnOrderedMap(m, "清空后的foo1:"); } int main() { UnOrderedMapExp1(); return 0; }
以类作为key,value
只是用STL提供的基本类型int, char, long等和stringz作为key,value,STL提供了哈希函数和比较函数。但是用自己定义的类时,需要自己定义哈希函数和比较函数//hash函数 template <typename T> class hash { public: size_t operator()(const T& o) const { return 0; } }; //compare函数 template <typename T> class equal_to { public: bool operator()(const T& a, const T& b) const { return a == b; } };
下面以一个学号姓名为例子来实现
#include <unordered_map> #include <iostream> #include <string> using namespace std; //自己设计类,作为key和value //学号 class Number { string str; public: Number() { } Number(string s) { str = s; } const string& get() const { return str; } }; //姓名 class Name { string str; public: Name() {} Name(string s) { str = s; } const string& get() const { return str; } }; //哈希函数对象实现 // 必须为const class MyHash { public: size_t operator()(const Number& num) const { hash<string> sh; //使用STL中hash<string> return sh(num.get()); } }; //实现equal_to对象 //必须为const class MyEqualTo { public: bool operator()(const Number& n1, const Number& n2) const { return n1.get() == n2.get(); } }; int main() { unordered_map<Number, Name, MyHash, MyEqualTo> map; map.emplace(Number("1000"), Name("A")); map.emplace(Number("1001"), Name("G")); map.emplace(Number("1002"), Name("E")); map.emplace(Number("1003"), Name("D")); unordered_map<Number, Name, MyHash, MyEqualTo>::iterator iter; Number num("1001"); iter = map.find(num); if (iter != map.end()) cout << "Number: " << iter->first.get() << "," << "Name: " << iter->second.get() << endl; else cout << "Not found!" << endl; return 0; }
参考:http://www.cplusplus.com/reference/unordered_map/unordered_map/
相关文章推荐
- C++封装POSIX 线程库(四)使用封装的线程
- C++之STL(7) queue队列
- VC++中subclassdlgitem函数的功能及用法
- NYOJ A+B IV 小数相加(大数问题)
- C++ map的基本操作和使用
- C++ 逻辑运算符总结
- C语言实现在控制台同一行覆盖刷新输出,以及'\b'退格控制字符的使用
- C++,C++编程,Windows编程,MFC
- 带分割符的参数提取 C语言
- C++ 11 新特性之类型推断与类型获取
- c语言dfs解决n皇后问题
- c语言dfs解决全排列问题
- C++之STL(6)之 map 与 multimap 关联容器
- C语言空指针总结
- 【学习笔记】 C++里面的绑定类型
- Cpp Primer - constexpr
- 设计模式总结2
- 一起talk C栗子吧(第一百七十八回:C语言实例--字符和字符串输出函数一)
- 李洪强漫谈iOS开发[C语言-024]-表达式与赋值运算符
- C++移位运算符