【C++ Primer 第11章】2. 关联容器操作
一、访问元素
关联容器额外类型别名
| key_type | 此容器类型的关键字类型 |
| mapped_type | 每个关键字关联的类型,只 适用于map |
| mapped_type | 对于set,与key_type相同 对于map,为pair<const key_type, mapped_type> |
二、关联容器迭代器
当解引用一个关联容器的迭代器时,我们会得到一个类型为容器的valued_type的值的引用。对map而言,value_type是一个pair类型,其first成员保存const的关键字,second成员保存值:
map<string, size_t> word_count
auto map_it = word_count.begin(); // *map_it是指向一个pair<const string,size_t>对象的引用 cout << map_it->first; // 打印此元素的关键字
cout << " " << map_it->second; // 打印此元素的值
map_it->first = "new key"; // 错误:关键字是const 的
++map_it->second; // 正确:我们可以通过迭代器改变元素
set的迭代器是const的
虽然set类型同时定义了iterator和const_iterator类型,但两种类型都只允许只读访问set中的元素。与不能改变一个map元素的关键字一样,一个set中的关键字也是const的,可以用一个set迭代器来读取元素的值,但不能修改:
set<int> iset = {, , , , , , , , , };
set<int>::iterator set_it = iset.begin();
if (set_it!=iset.end())
{
*set_it=; // 错误:set中的关键字是只读的
cout<<*set_it<<endl; // 正确:可以读关键字
}
遍历关联容器
map和set类型都支持begin和end操作。与往常一样,我们可以用这些函数获取迭代器,然后用迭代器类遍历容器。例如,我们可以编写一个循环程序来打印单词计数的结果,如下所示:
auto map_it=word_count.cbegin(); // 获取一个指向首元素的迭代器
while (map_it!=word_count.end()) // 比较当前迭代器和尾后迭代器
{
cout << map_it->first <<" occurs " << map_it->second << " times" <<endl; // 解引用迭代器,打印关键字-值对
++map_it; // 递增迭代器,移动到下一个元素
}
三、添加元素
对一个map进行insert操作时,必须记住元素类型是pair。通常,对于想要插入的数据,并没有一个现成的pair对象。可以在insert的参数列表中创建一个pair:
//向word_count插入word的4种方法
word_count.insert({word,});
word_count.insert(make_pair(word,));
word_count.insert(pair<string,size_t>(word,));
word_count.inset(map<string,size_t>::value_type(word,));
关联容器insert操作
| c.insert(v) |
1. v是value_type类型的对象; |
|
c.insert(b,e) |
1. b和e是迭代器,表示一个c::value_type类型值的范围;il是这种值的花括号列表。 |
| c.insert(p,v) | 1. 类似insert(v)但将迭代器p作为一个提示,指出从哪里开始搜索新元素应该存储的位置。返回一个迭代器,指向具有给定关键字的元素 |
#include<iostream>
#include<map>
#include<string>
using namespace std; int main()
{
map<string, size_t> word_count;
string word;
while (cin >> word)
{
auto ret = word_count.insert({ word, }); //
if (!ret.second)
++ret.first->second;
} for (auto c : word_count)
cout << c.first << "出现了" << c.second << "次" << endl;
return ;
}
运行结果:
四、删除元素
| c.erase(k) | 从c中删除每个关键字为k的元素,返回一个size_type值,指出删除的元素的数量 |
| c.erase(p) | 从c中删除迭代器p指定的元素,p必须指向c中一个真实元素,不能等于c.end().返回一个指向p之后元素的迭代器。若p指向c中的尾元素,则返回c.end() |
| c.erase(b,e) | 删除迭代器对b和e所表示的范围中的元素,返回e |
五、map的下标操作
对一个map使用下标操作,其行为与数组或vector上的下标操作很不相同:使用一个不在容器中的关键字作为下标,会添加一个具有此关键字的元素到map中
map和unordered_map的下标操作
| c[k] | 返回关键字为k的元素;如果k不做c中,添加一个关键字为k的元素,对其进行值初始化 |
| c.at(k) | 访问关键字为k的元素,带参数检查;若k不在c中,抛出一个out_of_range异常 |
六、访问元素
在multimap和multiset中查找元素
第一方法:
#include <iostream>
#include <map>
#include <string>
#include <utility>
using namespace std; int main()
{
multimap<string, string> author;
author.insert(make_pair("鲁迅", "朝花夕拾"));
author.insert(make_pair("鲁迅", "阿Q正传"));
author.insert(make_pair("鲁迅", "野草"));
author.insert(make_pair("罗贯中", "三国演义"));
author.insert(make_pair("罗贯中", "隋唐志传"));
author.insert(make_pair("琼瑶", "还珠格格"));
author.insert(make_pair("琼瑶", "情深深雨蒙蒙")); string search_find("鲁迅");
auto entries = author.count(search_find);
auto iter = author.find(search_find); cout << search_find << "的作品集:" << endl;
while (entries)
{
cout << iter->second << endl;
++iter;
--entries;
}
return ;
}
运行结果:

第二种方法:
c.lower_bound(k) 返回一个迭代器,指向第一个关键字不小于k的元素 >=
c.upper_bound(k) 返回一个迭代器,指向第一个关键字大于k的元素 >
lower_bound返回的迭代器将指向第一个具有给关键字的元素,而upper_bound返回的迭代器则指向最后一个匹配关键字的元素之后的位置,如果元素不在multimap中,则 lower_bound 和 upper_bound会返回相等迭代器——指向一个不影响排序的关键字插入位置。
#include <utility>
using namespace std; int main()
{
multimap<string, string> author;
author.insert(make_pair("鲁迅", "朝花夕拾"));
author.insert(make_pair("鲁迅", "阿Q正传"));
author.insert(make_pair("鲁迅", "野草"));
author.insert(make_pair("罗贯中", "三国演义"));
author.insert(make_pair("罗贯中", "隋唐志传"));
author.insert(make_pair("琼瑶", "还珠格格"));
author.insert(make_pair("琼瑶", "情深深雨蒙蒙")); string search_find("鲁迅");
cout << search_find << "的作品集:" << endl;
for (auto beg = author.lower_bound(search_find); beg != author.upper_bound(search_find); ++beg)
cout << beg->second << endl;
return ;
}
运行结果:

第三种方法:
c.equal_range(k): 返回一个迭代器pair,表示关键字等于k的元素的范围,若k不存在,pair的两个成员均等于c.end()
#include <iostream>
#include <map>
#include <string>
#include <utility>
using namespace std; int main()
{
multimap<string, string> author;
author.insert(make_pair("鲁迅", "朝花夕拾"));
author.insert(make_pair("鲁迅", "阿Q正传"));
author.insert(make_pair("鲁迅", "野草"));
author.insert(make_pair("罗贯中", "三国演义"));
author.insert(make_pair("罗贯中", "隋唐志传"));
author.insert(make_pair("琼瑶", "还珠格格"));
author.insert(make_pair("琼瑶", "情深深雨蒙蒙")); string search_find("鲁迅");
cout << search_find << "的作品集:" << endl;
for (auto pos = author.equal_range(search_find); pos.first != pos.second; ++pos.first)
cout << pos.first->second << endl;
return ;
}
运行结果:

【C++ Primer 第11章】2. 关联容器操作的更多相关文章
- [C++ Primer] : 第11章: 关联容器
目录 使用关联容器 关联容器概述 关联容器操作 无序容器 使用关联容器 关联容器与顺序容器有着根本的不同: 关联容器中的元素是按关键字来保存和访问的, 按顺序容器中的元素是按它们在容器中的位置来顺序保 ...
- 【足迹C++primer】38、关联容器操作(2)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/cutter_point/article/details/35244805 关联容器操作(2) map ...
- 第11章:sed进阶操作
第11章:sed进阶操作 sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法 sed命令行格式为 ...
- 【C++ Primer 第11章 练习答案】2. 关联容器操作
11.3.1节练习 [练习11.16]代码 map<int, int> m; auto iter = m.begin(); iter ->second = ;
- 【C++ Primer 第11章 练习答案】2. 关联容器概述
11.2.1节练习 [练习11.7]代码: #include<iostream> #include<string> #include<vector> #includ ...
- 【C++ Primer 第11章】4. 无序容器
一.介绍 1. Hashtable和bucket 由于unordered_map内部采用的hashtable的数据结构存储,所以,每个特定的key会通过一些特定的哈希运算映射到一个特定的位置,我们知道 ...
- 【C++ Primer 第13章】3. 交换操作
交换操作 class HasPtr { friend void swap(HasPtr &rhs, HasPtr &yhs); //其他成员定义 }; void swap(HasPtr ...
- 【c++ Prime 学习笔记】第11章 关联容器
关联容器的元素按照关键字来保存和访问,而顺序容器的元素是按照在容器中的位置来保存和访问 关联容器支持高效的关键字查找和访问 2种关联容器: map中的元素是关键字-值对(key-value对),关键字 ...
- C++ Primer笔记7_STL之关联容器
关联容器 与顺序容器不同,关联容器的元素是按keyword来訪问和保存的.而顺序容器中的元素是按他们在容器中的位置来顺序保存的. 关联容器最常见的是map.set.multimap.multiset ...
随机推荐
- jsp中的JSTL与EL表达式用法
JSTL (JSP Standard Tag Library ,JSP标准标签库) JSTL标签库分为5类:JSTL核心标签库.JSTL函数标签库.数据库标签库.I18N格式化标签库.XML标签库. ...
- 线程异步操作,更新其中一个报错不影响另一个的运行(Task )
//子系统同步更新 BD001_BLL bll = new BD001_BLL(); List<BD001_Model> lis ...
- elasticsearch 单机多实例
elasticsearch 配置单机器多实例 host: - - path data: /opt/elasticsearch/data/node1 /opt/elasticsearch/data/no ...
- [POI2007]ZAP-Queries (莫比乌斯反演+整除分块)
[POI2007]ZAP-Queries \(solution:\) 唉,数论实在有点烂了,昨天还会的,今天就不会了,周末刚证明的,今天全忘了,还不如早点写好题解. 这题首先我们可以列出来答案就是: ...
- Pytorch 各种奇葩古怪的使用方法
h1 { counter-reset: h2counter; } h2 { counter-reset: h3counter; } h3 { counter-reset: h4counter; } h ...
- 2018-2019-2 《网络对抗技术》Exp0 Kali安装 20165230
2018-2019-2 <网络对抗技术>Exp0 Kali安装 20165230 一.下载kali 下载地址 下载Kali Linux 64 bit VMware VM版本 下载vmwar ...
- Android常用逆向工具+单机游戏破解
android开发环境搭建 我理解的学习路线是首先要掌握和了解常见的工具.搭建环境.然后就是缓慢的积累特征,通过长期的练习使自己进步,通过android逆向课程的学习.常用的工具如下: android ...
- 【逆向工具】逆向工具101editor使用-游戏快速通关
[渡者游戏简介] 船夫小江将运送客人的,羊.狐狸.草等物品过河,如果留下动物被其它种类吃掉任务就失败了.你需要帮助他做出正确的顺序选择.Ferryman是一款根据经典谜题改编的解谜游戏. 一.查看文件 ...
- 【PE结构】PIMAGE_FILE_HEADER中TimeDateStamp的时间戳与标准时间转换
计算PE文件创建时间,需要对时间进行转换,也就是将时间戳转换成特定的格式,或者特定的格式转换成时间戳. pImageFileHeader->TimeDateStamp的值为1487665851 ...
- FreeSWITCH IVR中lua调用并执行nodejs代码
一.功能需求: 通过FreeSWITCH的IVR按键调用相应的脚本文件:nodejs提供很多的模组,可以方便的与其它系统或者进行任何形式的通讯,我的应用是通过nodejs发送http post请求: ...