C++Primer 第十一章
//1.关键容器支持高效的关键字查找和访问。
map 关联数组:保存关键字-值对。通过关键字来查找值。
set 关键字即值,即只保存关键字的容器。
multimap 关键字可重复出现的map
multiset 关键字可重复出现的set
//尚不研究无序关联容器
unordered_map 用哈希函数组织的map
unordered_set 用哈希函数组织的set
unordered_multimap 用哈希函数组织的map,关键字可重复出现
unordered_multiset 用哈希函数组织的set,关键字可以重复出现
// multiply ['mul·tiply]v. 乘
// 当初始化一个map的时候,必须提供关键字类型和值类型。
// 对于有序关联容器关键字类型必须定义元素比较的方法。有序关联容器都是默认按照<进行排序。
// 有multi前缀的关联容器的关键字是可以重复的,否则此关联容器的关键字都是不能重复的
// 不能改变关联容器的关键字部分,这就推出set系列的关联容器的元素不能被改变,map系列的关联容器的元素的first成员不能被改变。
// 关联容器默认使用关键字的<操作来比较关键字。 //2.关联容器的迭代器都是双向迭代器,不支持随机访问,这就意味着关联容器的迭代器不支持 += -= 等操作(包括map和unordered_map),除了map和unordered_map以外的关联容器也不能支持下标运算符操作。 //3.pair:定义在头文件utility中,当创建一个pair的时候必须提供两个类型名。
// pair定义的操作:
// A:make_pair:定义在命名空间std中,返回一个用传入值初始化(构造)的pair。
// B:first:返回pair中名为first的数据成员。
// C:second:返回pair中名为second的数据成员。
// == != :当first和second成员均相等的时候,两个pair相等。相等性由元素的==运算符判断。
// utility [u·til·i·ty]n. 公用程序 //4.关联容器的额外类型别名:(关联容器含有顺序容器中定义的类型别名)
// key_type:关键字类型
// mapped_type:每个关键字关联的类型,只适用于map系列的关键容器
// value_type:对于set系列的关键容器,与key_type相同,对于map系列的关键容器,为pair<const key_type, mapped_type> //5.当解引用关联容器的迭代器的时候,会得到一个类型为容器的value_type的值的引用。 //6.由于关联容器的读写限制,和其迭代器不支持随机访问,所以一般不对关联容器使用泛型算法,而是使用其本身的算法。
// 若是对关联容器使用泛型算法,也一般将其当做源序列或者是目的位置。 //7.对关联容器添加元素:使用insert和emplace
map<string, int> StrInt;
StrInt.insert(make_pair("", ));
StrInt.insert(make_pair("", ));
StrInt.insert(make_pair("", ));
//insert在插入单一元素的时候返回一个pair,其first成员是插入的元素,其second成员是插入的结果,成功为true,失败为false
//insert插入的时候,可以指定从哪里开始搜索插入的位置,对插入结果没有影响,应该会影响插入的效率
auto temValue = StrInt.insert(StrInt.begin(), make_pair("", ));
//StrInt = [4](("0", 0),("1", 1),("2", 2),("3", 3))
//temValue = (("2", 2), true) map<string, int> StrInt1;
//insert在插入一个序列的时候,返回void
StrInt1.insert(StrInt.begin(), StrInt.end());
//StrInt1 = [4](("0", 0),("1", 1),("2", 2),("3", 3)) map<string, unique_ptr<char[]>> StrChar;
StrChar.emplace(make_pair("", new char[]));
//insert是按值插入,emplace是构造插入 //8.关联容器删除元素:
map<string, int> StrInt;
StrInt.insert(make_pair("", ));
StrInt.insert(make_pair("", ));
StrInt.insert(make_pair("", ));
StrInt.insert(StrInt.end(), make_pair("", )); //StrInt = [4](("0", 0),("1", 1),("2", 2),("3", 3))
map<string, int>::size_type value = StrInt.erase(string("")); //value = 1 StrInt = [3](("1", 1),("2", 2),("3", 3))
//erase:第一个版本,删除关联容器中每个关键字为传入参数的元素,返回删除元素的数量 StrInt.erase(StrInt.begin()); //StrInt = [2](("2", 2),("3", 3))
//erase:第二个版本,删除关联容器中指定迭代器所指的元素 StrInt.erase(StrInt.begin(), StrInt.end()); //StrInt = [0]()
//erase:第三个版本,删除关联容器中指定迭代器序列所指的元素 //9.map和unordered_map容器提供了下标运算符和at()成员函数,通过传入关键字来得到与关键字绑定的值。注意点:当关键字不在指定的容器中的时候,下标运算符会为其创建一个值初始化的值与关键字绑定并插入指定容器,而使用at()的时候则会报out_of_range的错误。
// 由于下标运算符可能插入一个新元素,所以只能对非const的map或者unordered_map进行下标操作。
// 通常情况下,一个容器的下标的返回值和其迭代器解引用的返回值的类型是一致的,但是对于map和unordered_map来说,下标运算符返回类型是mapped_type,解引用迭代器返回类型是value_type
// 此处的下标运算符返回的是左值,所以可以读写元素。 //10.关联容器中的查找操作:
c.find(k):返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回尾后迭代器
c.count(k):返回关键字等于k的元素的数量。
c.lower_bound(k):返回一个迭代器,指向第一个关键字不小于k的元素。换句话说,此函数返回的迭代器指向第一个具有给定关键字的元素。
c.upper_bound(k):返回一个迭代器,指向第一个关键字大于k的元素。换句话说,此函数返回的迭代器指向最后一个匹配给定关键字的元素之后的元素。
c.equal_range(k):返回一个迭代器pair,若关键字存在,则第一个迭代器指向第一个与关键字匹配的元素,第二个迭代器指向最后一个匹配元素之后的位置。若未找到元素,则两个迭代器都指向关键字可以插入的位置。
//当给定的关键字不在序列中的时候,lower_bound和upper_bound返回值相同,返回关键字的第一个安全插入点,即不影响容器中元素顺序的插入位置。
int _tmain(int argc, _TCHAR* argv[])
{
const int CCount = 1e6;
const int CTime = 50;
vector<int> vecInt;
unsigned long long nT0 = GetTickCount64();
for (int i = 0; i < CCount; ++i)
{
vecInt.emplace_back(i);
}
unsigned long long nT1 = GetTickCount64() - nT0; //nT1 = 124
map<int, int> mapInt;
unsigned long long nT2 = GetTickCount64();
for (int i = 0; i < CCount; ++i)
{
mapInt.emplace(make_pair(i, i));
}
unsigned long long nT3 = GetTickCount64() - nT2; //nT3 = 3869
unsigned long long t0 = GetTickCount64();
for (int i = 0; i < CTime; ++i)
{
find_if(vecInt.begin(), vecInt.end(), [CCount](int &i){return i == CCount - 1;});
}
unsigned long long t1 = GetTickCount64() - t0; //t1 = 546
unsigned long long t2 = GetTickCount64();
for (int i = 0; i < CTime; ++i)
{
find_if(mapInt.begin(), mapInt.end(), [CCount](map<int, int>::value_type &v){return v.second == CCount - 1;});
}
unsigned long long t3 = GetTickCount64() - t2; //t3 = 6271
unsigned long long t4 = GetTickCount64();
for (int i = 0; i < CTime; ++i)
{
mapInt.find(CCount - 1);
}
unsigned long long t5 = GetTickCount64() - t4; //t5 = 0
}
//map会维护插入元素的顺序,所以插入慢,但是使用map本身的find来查找却非常快
//11.关联容器支持通过关键字查找和提取元素。对关键字的使用将关联容器和顺序容器区分开,顺序容器是通过位置访问元素。
C++Primer 第十一章的更多相关文章
- C++ Primer : 第十一章 : 关联容器示例: 一个单词转换的map
单词转换就是:将一些缩写的单词转换为实际的文本.第一个文件保存的是转换的规则,而第二个文件保存的是要转换的文本. 假设单词转换的规则的文件如下: brb be right back k okay? y ...
- C++ Primer : 第十一章 : 关联容器之关联容器的迭代器和操作
关联容器的操作 除了和顺序容器定义的类型之外,关联容器还定义了一下几种类型: 关联容器额外的类型别名 key_type 此容器类型的关键字类型 mapped_type 每个关键字关联的类型, ...
- C++ Primer : 第十一章 : 关联容器之概述、有序关联容器关键字要求和pair类型
标准库定义了两种主要的关联容器:map和set map中的元素时一些关键字-值(key-value)对,关键字起到索引的作用,值则表示与索引相关的数据.set中每个元素只包含一个关键字,可以完成高效的 ...
- 【C++】《C++ Primer 》第十一章
第十一章 关联容器 关联容器和顺序容器的不同:关联容器中的元素时按照关键字来保存和访问的. 关联容器支持通过关键字来高效地查找和读取元素,基本的关联容器类型是 map和 set. 类型 map 和 m ...
- CPrimerPlus第十一章中的“选择排序算法”学习
C Primer Plus第十一章字符串排序程序11.25中,涉及到“选择排序算法”,这也是找工作笔试或面试可能会遇到的题目,下面谈谈自己的理解. 举个例子:对数组num[5]={3,5,2,1,4} ...
- <构建之法>第十一章、十二章有感
十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)
第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的 DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...
- 第十一章 TClientDataSet
第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...
- 第十一章、认识与学习BASH
第十一章.认识与学习 BASH 最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 ...
随机推荐
- Python实用工具包Scrapy安装教程
对于想用每个想用Python开发网络爬虫的开发者来说,Scrapy无疑是一个极好的开源工具.今天安装之后觉得Scrapy的安装确实不易啊.所以在此博文一篇,往后来着少走弯路. 废话不多说了,如果 ...
- attr-img-src
https://dev.w3.org/html5/spec-preview/the-img-element.html#attr-img-src The src attribute must be pr ...
- html5之canvas初解
<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器) - 必须使用脚本来完成实际的绘图任务. getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属 ...
- Tab指示符——Indicator
先说说我们的思路吧. 其实思路也很简单,就是在咱们的导航下面画一个小矩形,不断的改变这个矩形距离左边的位置. 思路就这么简单,有了思路,接下来就是实现了,看代码: public class Indic ...
- C#引用类型与值类型的比较
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SimpleDe ...
- 实验三--for语句及分支结构else-if
本节课学习到的知识点: 1.for语句的表达式的应用与掌握.流程形式. 2.多分支else-if,用来判断真假等. 实验中遇到的问题及解决方法: 这次课的逻辑要求比之前的课要难许多,而且对于一些数学逻 ...
- 【C51】单片机芯片之——图解74HC595
第一部部分用于快速查阅使用,详细的使用见文章第二部分 引脚图
- 流媒体学习一-------mediastreamer2 的简介
Mediastreamer2 是一个功能强大且小巧的流引擎,专门为音视频电话应用而开发.这个库为linphone中所有的接收.发送多媒体流提供处理,包括音/视频捕获,编码和解码,渲染. 特性: 接收. ...
- 使用Areas分离ASP.NET MVC项目
为什么需要分离? 我们知道MVC项目各部分职责比较清晰,相比较ASP.NET Webform而言,MVC项目的业务逻辑和页面展现较好地分离开来,这样的做法有许多优点,比如可测试,易扩展等等.但是在实际 ...
- c# 过滤字符串中的重复字符
有字符串"a,s,d,v,a,v",如果想去除其中重复的字符,怎么做? 下面是一个方法,用Hashtable来记录唯一字符,排除重复字符,仅供参考. 1.过滤方法: public ...