C++中的unordered_map常见用法详解
文章目录
- 1. std::unordered_map 的定义与特性
- 2. 构造 std::unordered_map
- 3. 赋值操作
- 4. 迭代器操作
- 4.1 指向整个容器中的元素
- 4.2 指向某个桶中的元素
- 5. 容量操作
- 6. 访问操作
- 7. 插入操作
- 8. 删除操作
- 9. 查找操作
- 10. 桶操作
1. std::unordered_map 的定义与特性
所在头文件:
<unordered_map>
std::unorederd_map
类模板:
template < class Key, // unordered_map::key_typeclass T, // unordered_map::mapped_typeclass Hash = hash<Key>, // unordered_map::hasherclass Pred = equal_to<Key>, // unordered_map::key_equalclass Alloc = allocator< pair<const Key,T> > // unordered_map::allocator_type> class unordered_map;
关联性:std::unorederd_map 是一个关联容器,其中的元素根据键来引用,而不是根据索引来引用。
无序性:在内部,std::unordered_map中的元素不会根据其键值或映射值按任何特定顺序排序,而是根据其哈希值组织到桶中,以允许通过键值直接快速访问各个元素(常量的平均时间复杂度)。
唯一性:std::unorederd_map中的元素的键是唯一的。
一些类型定义:
类型成员 | 定义 |
---|---|
key_type | 第一个模板参数(Key) |
mapped_type | 第二个模板参数(T) |
value_type | pair<const key_type,mapped_type> |
hasher | 第三个模板参数(Hash) |
key_equal | 第四个模板参数(Pred) |
2. 构造 std::unordered_map
构造方式 | 函数声明 |
---|---|
构造空的 unordered_map |
explicit unordered_map ( size_type n = /* see below */, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& alloc = allocator_type() ); explicit unordered_map ( const allocator_type& alloc ); |
由一对范围迭代器指定输入 |
template <class InputIterator> unordered_map(InputIterator first, InputIterator last, size_type n = /* see below */, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& alloc = allocator_type() ); |
复制构造 |
unordered_map ( const unordered_map& ump ); unordered_map ( const unordered_map& ump, const allocator_type& alloc ); |
移动构造 |
unordered_map ( unordered_map&& ump ); unordered_map ( unordered_map&& ump, const allocator_type& alloc ); |
利用初始化列表构造 |
unordered_map (initializer_list<value_type> il, size_type n = /* see below */, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& alloc = allocator_type() ); |
参数解释:
n : 初始时,桶的最小数量,即最少有多少个桶。
hf : 哈希函数对象。它是一个函数,根据传递给它的键计算并返回一个整数。
eql : 比较函数对象。如果传递给它的两个参数相等,则返回true.
例子:
// constructing unordered_maps
#include <iostream>
#include <string>
#include <unordered_map>typedef std::unordered_map<std::string,std::string> stringmap;stringmap merge (stringmap a,stringmap b) {stringmap temp(a); temp.insert(b.begin(),b.end()); return temp;
}int main () {stringmap first; // empty// 一个元素为:{key, value}stringmap second ( {{"apple","red"}, {"lemon","yellow"}} ); // init liststringmap third ( {{"orange","orange"}, {"strawberry","red"}} ); // init liststringmap fourth (second); // copystringmap fifth (merge(third,fourth)); // movestringmap sixth (fifth.begin(),fifth.end()); // rangestd::cout << "sixth contains:"<<endl;for (auto& x: sixth) std::cout << x.first << ":" << x.second<<endl;std::cout << std::endl;system("pause");return 0;
}
运行结果:
3. 赋值操作
赋值方式 | 函数声明 |
---|---|
复制 | unordered_map& operator= ( const unordered_map& ump ); |
移动 | unordered_map& operator= ( unordered_map&& ump ); |
初始化列表 | unordered_map& operator= ( intitializer_list<value_type> il ); |
例子:
// assignment operator with unordered_map
#include <iostream>
#include <string>
#include <unordered_map>typedef std::unordered_map<std::string, std::string> stringmap;stringmap merge(stringmap a, stringmap b) {stringmap temp(a);temp.insert(b.begin(), b.end());return temp;
}int main() {//stringmap first, second, third;//此处连续定义三个会报错。stringmap first = { { "AAPL", "Apple" }, { "MSFT", "Microsoft" } }; // init liststringmap second = { { "GOOG", "Google" }, { "ORCL", "Oracle" } }; // init liststringmap third = merge(first, second); // movefirst = third; // copystd::cout << "first contains:"<<std::endl;for (auto& elem : first)std::cout << elem.first << ":" << elem.second<<std::endl;std::cout << std::endl;system("pause");return 0;
}
运行结果:
4. 迭代器操作
4.1 指向整个容器中的元素
即,“第一个”指整个容器中的第一个,“尾后”指整个容器中的尾后。
函数声明 | 解释 |
---|---|
iterator begin() noexcept; const_iterator begin() const noexcept; |
返回一个迭代器,指向第一个元素 |
iterator end() noexcept; const_iterator end() const noexcept; |
返回一个迭代器,指向尾后元素 |
const_iterator cbegin() const noexcept; | 返回一个常量迭代器,指向第一个元素 |
const_iterator cend() const noexcept; | 返回一个常量迭代器,指向尾后元素 |
4.2 指向某个桶中的元素
即,“第一个”指某个桶中的第一个,“尾后”指某个桶中的尾后。
函数声明 | 解释 |
---|---|
local_iterator begin( size_type n ); const_local_iterator begin ( size_type n ) const; |
返回一个迭代器,指向第n个桶内的第一个元素 |
local_iterator end(size_type n); const_local_iterator end (size_type n) const; |
返回一个迭代器,指向第n个桶内的尾后元素 |
const_local_iterator cbegin( size_type n ) const; | 返回一个常量迭代器,指向第n个桶内的第一个元素 |
const_local_iterator cend( size_type n ) const; | 返回一个常量迭代器,指向第n个桶内的尾后元素 |
例子:
// unordered_map::cbegin/cend example
#include <iostream>
#include <string>
#include <unordered_map>int main() {std::unordered_map<std::string, std::string> mymap= { { "Australia", "Canberra" }, { "U.S.", "Washington" }, { "France", "Paris" } };std::cout << "mymap contains:"<<std::endl;for (auto it = mymap.cbegin(); it != mymap.cend(); ++it)std::cout << it->first << ":" << it->second<<std::endl; // cannot modify *itstd::cout << std::endl;std::cout << "mymap's buckets contain:\n";for (unsigned i = 0; i < mymap.bucket_count(); ++i) {std::cout << "bucket #" << i << " contains:";for (auto local_it = mymap.cbegin(i); local_it != mymap.cend(i); ++local_it)std::cout << local_it->first << ":" << local_it->second;std::cout << std::endl;}system("pause");return 0;
}
运行结果:
5. 容量操作
函数声明 | 解释 |
---|---|
bool empty() const noexcept; | unordered_map 是否为空 |
size_type size() const noexcept; | 获取unordered_map 中元素的数量 |
6. 访问操作
访问方式 | 函数声明 | 解释 |
---|---|---|
使用方括号([]) |
mapped_type& operator[] (const key_type& k);
mapped_type& operator[] (key_type&& k); |
如果 k 匹配容器中某个元素的键,则该函数返回该映射值的引用。
如果 k 与容器中任何元素的键都不匹配,则该函数将使用该键插入一个新元素,并返回该映射值的引用。 |
使用 at() |
mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const; |
如果 k 匹配容器中某个元素的键,则该函数返回该映射值的引用。
如果 k 与容器中任何元素的键都不匹配,则该函数将抛出 out_of_range 异常。 |
注意:const std::unordered_map 不能使用 operator[] 操作!!
例子:
// unordered_map::at
#include <iostream>
#include <string>
#include <unordered_map>int main() {std::unordered_map<std::string, int> mymap = {{ "Mars", 3000 },{ "Saturn", 60000 },{ "Jupiter", 70000 } };mymap.at("Mars") = 3396;mymap.at("Saturn") += 272;mymap.at("Jupiter") = mymap.at("Saturn") + 9638;for (auto& x : mymap) {std::cout << x.first << ": " << x.second << std::endl;}system("pause");return 0;
}
运行结果:
7. 插入操作
插入方式 | 函数声明 | 说明 |
---|---|---|
插入单个元素 |
pair<iterator,bool> insert (const value_type& val);
template <class P> |
返回一个pair,其中第一个值为一个迭代器,指向新插入的元素或其键等于待插入元素的键的元素(原先就已存在的元素);第二个值是一个bool值,当插入一个新元素时,该值设为true,当该键已存在时,该值设为false |
带插入位置提示 |
iterator insert (const_iterator position, const value_type& val);
template <class P> |
返回一个迭代器,该迭代器指向新插入的元素或指向键相等的已存在元素。 |
由一对范围迭代器指定输入 |
template <class InputIterator> void insert (InputIterator first, InputIterator last); |
|
使用初始化列表指定插入元素 | void insert (initializer_list<value_type> il); |
例子:
// unordered_map::insert
#include <iostream>
#include <string>
#include <unordered_map>int main() {std::unordered_map<std::string, double>myrecipe,mypantry = { { "milk", 2.0 }, { "flour", 1.5 } };std::pair<std::string, double> myshopping("baking powder", 0.3);myrecipe.insert(myshopping); // copy insertionmyrecipe.insert(std::make_pair<std::string, double>("eggs", 6.0)); // move insertionmyrecipe.insert(mypantry.begin(), mypantry.end()); // range insertionmyrecipe.insert({ { "sugar", 0.8 }, { "salt", 0.1 } }); // initializer list insertionstd::cout << "myrecipe contains:" << std::endl;for (auto& x : myrecipe)std::cout << x.first << ": " << x.second << std::endl;std::cout << std::endl;system("pause");return 0;
}
运行结果:
8. 删除操作
删除方式 | 函数声明 | 说明 |
---|---|---|
根据元素位置 | iterator erase (const_iterator position); | 返回一个迭代器,指向被删除元素的后一个元素 |
根据元素的键 | size_type erase (const key_type& k); | 返回被删除元素的数目,此处为1 |
由一对范围迭代器指定删除的范围 | iterator erase (const_iterator first, const_iterator last); | 返回一个迭代器,指向最后一个被删除元素的后一个元素 |
删除所有元素 | void clear() noexcept; |
例子:
// unordered_map::erase
#include <iostream>
#include <string>
#include <unordered_map>int main() {std::unordered_map<std::string, std::string> mymap;// populating container:mymap["U.S."] = "Washington";mymap["U.K."] = "London";mymap["France"] = "Paris";mymap["Russia"] = "Moscow";mymap["China"] = "Beijing";mymap["Germany"] = "Berlin";mymap["Japan"] = "Tokyo";// erase examples:mymap.erase(mymap.begin()); // erasing by iteratormymap.erase("France"); // erasing by keymymap.erase(mymap.find("China"), mymap.end()); // erasing by range// show content:for (auto& x : mymap)std::cout << x.first << ": " << x.second << std::endl;system("pause");return 0;
}
运行结果:
9. 查找操作
函数声明 | 说明 |
---|---|
iterator find (const key_type& k);
const_iterator find (const key_type& k) const; |
在容器中搜索键值等于 k 的元素,如果找到,则返回一个指向该元素的迭代器,否则返回一个指向unordered_map :: end的迭代器。 |
例子:
// unordered_map::find
#include <iostream>
#include <string>
#include <unordered_map>int main () {std::unordered_map<std::string,double> mymap = {{"mom",5.4},{"dad",6.1},{"bro",5.9} };std::string input;std::cout << "who? ";getline (std::cin,input);// 查找std::unordered_map<std::string,double>::const_iterator got = mymap.find (input);if ( got == mymap.end() )std::cout << "not found";elsestd::cout << got->first << " is " << got->second;std::cout << std::endl;system("pause");return 0;
}
运行结果:
10. 桶操作
函数声明 | 说明 |
---|---|
size_type bucket_count() const noexcept; | 获取容器中桶的数目 |
size_type bucket_size ( size_type n ) const; | 获取第 n 个桶中元素的数量 |
size_type bucket ( const key_type& k ) const; | 获取键为 k 的元素所在桶的序号 |
参考:http://www.cplusplus.com/reference/unordered_map/unordered_map/
以上博文来自:
- W.T.F._C++ std::unordered_map 用法详解
C++中的unordered_map常见用法详解相关推荐
- Linux中head和tail命令作用,Linux 命令head和tail常见用法详解
head和tail是一组想对应的命令,默认分别显示文件的开头和末尾10行记录. head head 命令可以将一段文本的开头一部分输出到标准输出. head命令既可以处理文本文件也可以处理标准输入. ...
- escape mysql_MySQL中ESCAPE关键字的用法详解
MySQL转义 转义即表示转义字符原来的语义,一个转义字符的目的是开始一个字符序列,使得转义字符开头的该字符序列具有不同于该字符序列单独出现时的语义. MySQL中,转义字符以"" ...
- MySQL中ESCAPE关键字的用法详解
MySQL中ESCAPE关键字的用法详解 MySQL中ESCAPE关键字的用法详解 1. mysql转义概述 2. escape验证 MySQL中ESCAPE关键字的用法详解 1. mysql转义概述 ...
- 《算法笔记》学习日记——6.1 vector的常见用法详解
目录 6.1 vector的常见用法详解 问题 A: Course List for Student (25) 问题 B: Student List for Course (25) 小结 6.1 ve ...
- mysql escape关键字_MySQL中ESCAPE关键字的用法详解
MySQL转义 转义即表示转义字符原来的语义,一个转义字符的目的是开始一个字符序列,使得转义字符开头的该字符序列具有不同于该字符序列单独出现时的语义. MySQL中,转义字符以"\" ...
- linux lvm2,LVM2常见用法详解
LVM2常见用法详解 1.简介 LVM(Logical Volume Manager)是逻辑卷管理的意思,是linux环境下对磁盘分区进行管理的一种机制,lvm是建立在硬盘和分区之上的一个逻辑层,来提 ...
- CSS3中font-face属性的用法详解
CSS3中font-face属性的用法详解 @font-face是CSS3中的一个模块,主要是把自定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕 ...
- csh for循环_shell中的for循环用法详解_linux shell
这篇文章主要介绍了shell中的for循环用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 for 命令: for i i ...
- conv2d的输入_pytorch1.0中torch.nn.Conv2d用法详解
Conv2d的简单使用 torch 包 nn 中 Conv2d 的用法与 tensorflow 中类似,但不完全一样. 在 torch 中,Conv2d 有几个基本的参数,分别是 in_channel ...
最新文章
- 求过去9天的相同时刻的平均值的sql(MYSQL)语句(去掉最大值,最小值)
- ASP.NET的用户控件
- 计算机系统字的描述性定义,CTCS系统11CTCS系统描述定义
- 填谷式无源pfc电路_有源PFC电路上各个元件的作用-安泰维修
- MySQL之架构与历史(二)
- 《C和指针》读书笔记
- hibernate中主键的生成策略
- linux 重庆mysql_Linux服务器上MYSQL的安装
- docker mysql 主从配置
- STL---常用函数用法大集合-=-更新中...
- 低头编码的程序员们,你们颈椎不疼吗?
- 怎么更改计算机的注册表,Windows如何一键修改注册表
- mysql8忘记密码后重置密码
- python调用函数出现未定义_python中函数调用中的“未定义”参数
- js实现鼠标移动到div背景颜色变换,移开还原
- 数据库完整性--断言和触发器
- Oracle数据库字段翻译
- 下载频道2013年超人气精华资源汇总---全都是免积分下载
- 华为交换机eth口作用_华为的交换机有什么用
- 网络安全 - 一名合格的Web安全工程师之成长路径
热门文章
- AI教程之 Stable Diffusion在自己电脑上运行稳定的AI自动艺术创作
- 【论文阅读笔记】Integral Human Pose Regression
- 高通骁龙845的android手机有哪些,骁龙845手机有哪些 2018搭载高通骁龙845的手机推荐...
- 清华大学计算机科学王昊,日照最好的三所高中,新鲜出炉!
- mysql存储emoji表情_MySQL中支持emoji表情的存储
- 农民工工地受伤是否就可以申请工伤?
- 5G尚未完全覆盖,运营商开始采取措施降低5G投资
- HTML+CSS实战提升
- js中box和box()的区别
- 360 css grid,CSS Grid 網格佈局教程