C++ Primer : 第十一章 : 关联容器之概述、有序关联容器关键字要求和pair类型
标准库定义了两种主要的关联容器:map和set
map中的元素时一些关键字-值(key-value)对,关键字起到索引的作用,值则表示与索引相关的数据。set中每个元素只包含一个关键字,可以完成高效的关键字查询操作。
由map和set延伸出来一共8个关联容器,或者是一个map,或者是一个set,multi开头的是可以重复关键字的关联容器,unordered_开头的是无序关联容器。unordered_multi开头的是允许重复关键字的无序关联容器。
map和multimap定义在头文件<map>中,set和multiset定义在<set>中,4个无序容器分别定义在<unordered_map>和<unordered_set>中。
1.使用map:
map<string, size_t> words;
string word;
while (cin >> word)
++words[word];
for (const auto elmt : words)
cout << elmt.first << elmt.second << endl;
我们定义了一个map,关键字是string类型,值为size_t类型,每次从标准输入读一个单词,将这个单词的计数+1,如果words离不存在word,则创建一个word。
最后,打印出words内容,map的元素类型时pair,first成员表示关键字,second成员表示值。
2. 使用set
map<string, size_t> words;
set<string> exclude = {"The", "But", "And", "Or"}; string word;
while (cin >> word)
if (exclude.find(word) == exclude.end())
++words[word];
set保存了我们想要忽略的单词,在if判断里,如果word不在set exclude里,find成员函数返回尾后迭代器,并将这个单词的计数+1.
定义关联容器
定义一个map时,我们必须既指明关键字类型又指明值的类型,定义一个set时,只需指明关键字类型就可以,因为set的关键字就是值。
而初始化一个map时,必须提供关键字类型和值类型,我们将一对关键字-值放在一个花括号里: { key, value};
一个map或set的关键字是唯一的,multimap和multiset没有这个限制,初始化一个multimap或multiset时,可以重复关键字:
vector<int> vec;
for (vector<int>::size_type i = 0; i < 10; ++i){
// 每个关键字重复一次
vec.push_back(i);
vec.push_back(i);
} set<int> st(vec.begin(), vec.end());
multiset<int> mltst(vec.begin(), vec.end()); cout << vec.size() << endl; // 输出20
cout << st.size() << endl; // 输出10
cout << mltst.size() << endl; // 输出20
- 关键字类型的要求(非常重要!)
关联容器对关键字的类型有一定的要求,先讲有序容器, 关键字类型必须定义元素的比较方法,默认情况下,标准库使用关键字类型的 < 运算符来比较关键字。
传递给排序算法的可调用对象必须满足与关联容器中关键字一样的类型要求。
可以向算法提供我们自己定义的比较操作,类似的,我们也可以提供自己定义的操作来代替关键字的 < 运算符。所提供的操作必须在关键字类型上定义一个严格弱序
它具备以下性质:
- 两个关键字不能同时"小于等于"对方;如果 k1 "小于等于" k2,那么k2绝不能 "小于等于" k1.
- 如果k1 "小于等于" k2, 且k2 "小于等于" k3, 那么k1必须 "小于等于" k3.
- 如果存在两个关键字,任何一个都不 "小于等于" 另一个, 那么我们称这两个关键字是 "等价的"。如果 k1 "等价于" k2, k2 "等价于" k3,那么k1必须 "等价于" k3.
实际编程中,重要的是,如果一个类型定义了行为正常的 < 运算符,则它可以用作关键字类型。
我们定义一个类叫 Sales_data, 它又一个成员函数为compareIsbn, 用来比较它的成员isbn, 则我们可以用map来保存一个Sales_data类:
bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs) {
return lhs.isbn < rhs.isbn;
}
map<Sales_data, decltype(compareIsbn)*> Smap(compareIsbn);
我们使用decltype来指出自定义操作的类型,当使用decltype获取一个函数指针类型时必须加上一个 * 来指出我们需要一个函数指针类型。我们使用compareIsbn来初始化Smap, 表示我们向Smap中添加元素时,根据compareIsbn来为元素排序。
pair类型
pair类型定义在头文件 <utility>中。一个pair保存两个数据成员,当创建一个pair时,我们需要指出两个类型名。
pair<T1, T2> p; p是一个pair类型,对两个类型分别为T1和 T2的成员进行值初始化
pair<T1, T2> p(v1, v2); v1和v2分别对p的first和second成员进行初始化
pair<T1, T2> p = {v1, v2}; 等价于p(v1, v2) make_pair(v1, v2); 函数返回一个用v1和v2初始化的pair,pair的类型从v1和v2推断出来 p.first; 返回p的名为first(共有的)的数据成员
p.second; 返回p的名为second(共有的)的数据成员 p1 relop p2 关系运算符(< <= > >=)按字典序定义: 当p1.first < p2.first或 !(p2.first < p1.first) && p1.second < p2.second 成立时,p1 < p2 p1 == p2 当first和second成员分别相等时,两个pair相等。
p1 != p2
创建pair对象的函数:
假如一个函数返回pair类型,我们可以这样返回:
pair<string, int>
process(vector<string>& v) {
if (!v.empty())
return {v.back(), v.back().size()}; // 列表初始化
else
return pair<string, int>(); // 隐式构造返回值
}
除了这两种,我们还可以使用make_pair来生成pair对象:
if (!v.empty())
return make_pair(v.back(), v.back().size());
C++ Primer : 第十一章 : 关联容器之概述、有序关联容器关键字要求和pair类型的更多相关文章
- C++ Primer : 第十一章 : 关联容器之关联容器的迭代器和操作
关联容器的操作 除了和顺序容器定义的类型之外,关联容器还定义了一下几种类型: 关联容器额外的类型别名 key_type 此容器类型的关键字类型 mapped_type 每个关键字关联的类型, ...
- C++Primer 第十一章
//1.关键容器支持高效的关键字查找和访问. map 关联数组:保存关键字-值对.通过关键字来查找值. set 关键字即值,即只保存关键字的容器. multimap 关键字可重复出现的map mult ...
- C++ Primer : 第十一章 : 关联容器示例: 一个单词转换的map
单词转换就是:将一些缩写的单词转换为实际的文本.第一个文件保存的是转换的规则,而第二个文件保存的是要转换的文本. 假设单词转换的规则的文件如下: brb be right back k okay? y ...
- 第十一章:使用Apriori算法进行关联分析
- 第十一章:random库概述
random库是使用随机数的python标准库 伪随机数:采用梅森旋转算法生成的伪随机序列中的元素 random库主要用于产生随机数 使用random库:import random random库的概 ...
- C++ Primer 第3章 字符串、向量和数组
C++ Primer 第3章 字符串.向量和数组 C Primer 第3章 字符串向量和数组 1 命名空间的using声明 2 标准库类型string 3 标准库类型vector 4 迭代器介绍 5 ...
- File类与常用IO流第十一章——打印流
第十一章.打印流 概述:java.io.PrintStream extends OutputStream,为其他输出流添加了功能,使题目能够方便的打印各种数据值表示形式. 特点: 只负责数据的输出,不 ...
- 【C++ Primer 第11章】2. 关联容器操作
练习答案 一.访问元素 关联容器额外类型别名 key_type 此容器类型的关键字类型 mapped_type 每个关键字关联的类型,只 适用于map mapped_type 对于set,与key_ ...
- [C++ Primer] : 第11章: 关联容器
目录 使用关联容器 关联容器概述 关联容器操作 无序容器 使用关联容器 关联容器与顺序容器有着根本的不同: 关联容器中的元素是按关键字来保存和访问的, 按顺序容器中的元素是按它们在容器中的位置来顺序保 ...
随机推荐
- 戴文的Linux内核专题:01介绍
转自Linux中国 译者按:本文作者戴文.科利尔.约翰逊(Devyn Collier Johnson)今年才19岁,但是他在Linux内核.人工智能.编程语言方面拥有丰富的经验,本文是其在linux. ...
- 全国行政区划代码(json对象版)
var area = {"110000":"北京市","110100":"北京市","110101" ...
- Cisco IOS Security command Guide
copy system:running-config nvram:startup-config : to save your configuration changes to the startup ...
- SharePoint 2013 开发——构建工作流开发环境
博客地址:http://blog.csdn.net/FoxDave 本篇我们来讲述一下如何搭建SharePoint 2013工作流开发环境. Windows Azure Workflow作为单独的可下 ...
- 修改Azure Website 移动服务 默认时区
Azure Website 默认时区为国际标准时间,对中国用户来说不太方便友好,如何设置成北京时间呢? 打开Azure Website的“配置”页,找到“应用设置”节点. 在应用设置中添加设置项,密钥 ...
- ognl表达式root中取值顺序
不加#,先从栈顶取,如果没有(是没有这个属性而不是这个属性没有值),再往下取. 如果栈顶和非栈顶的对象拥有同一个属性名称,想直接取非栈顶的属性可以在ognl中用#root[i].属性名,可以取到属性的 ...
- lib静态链接库,dll动态链接库,h文件
最近在弄摄像头,发现我在调用摄像头自带的函数的时候,库没连接上,于是经过高人指点,学习了一下lib静态链接库,dll动态链接库来补充一下自己的基础知识. 一.首先我们来介绍一下lib静态链接库. li ...
- linux基础命令学习(四)计划任务
一.计划任务 crond服务简介 linux任务调度的工作主要分为以下两类: *系统执行的工作:系统周期性所要执行的工作,如备份系统数据.清理缓存 *个人执行的工作:某个用户定期要做的工作,例如每隔1 ...
- 监听Android CTS测试项解决方案(二)
二,监听当前测试项是否是Accelerometer Measurement Test测试项 通过第一种方式介绍的,我们可以得到当前处于活动状态的Activity类似监听CTS测试当前的测试项.但是由于 ...
- BZOJ 2292 永远挑战
最短路. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm&g ...