//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 第十一章的更多相关文章

  1. C++ Primer : 第十一章 : 关联容器示例: 一个单词转换的map

    单词转换就是:将一些缩写的单词转换为实际的文本.第一个文件保存的是转换的规则,而第二个文件保存的是要转换的文本. 假设单词转换的规则的文件如下: brb be right back k okay? y ...

  2. C++ Primer : 第十一章 : 关联容器之关联容器的迭代器和操作

    关联容器的操作 除了和顺序容器定义的类型之外,关联容器还定义了一下几种类型: 关联容器额外的类型别名  key_type    此容器类型的关键字类型 mapped_type  每个关键字关联的类型, ...

  3. C++ Primer : 第十一章 : 关联容器之概述、有序关联容器关键字要求和pair类型

    标准库定义了两种主要的关联容器:map和set map中的元素时一些关键字-值(key-value)对,关键字起到索引的作用,值则表示与索引相关的数据.set中每个元素只包含一个关键字,可以完成高效的 ...

  4. 【C++】《C++ Primer 》第十一章

    第十一章 关联容器 关联容器和顺序容器的不同:关联容器中的元素时按照关键字来保存和访问的. 关联容器支持通过关键字来高效地查找和读取元素,基本的关联容器类型是 map和 set. 类型 map 和 m ...

  5. CPrimerPlus第十一章中的“选择排序算法”学习

    C Primer Plus第十一章字符串排序程序11.25中,涉及到“选择排序算法”,这也是找工作笔试或面试可能会遇到的题目,下面谈谈自己的理解. 举个例子:对数组num[5]={3,5,2,1,4} ...

  6. <构建之法>第十一章、十二章有感

    十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...

  7. sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)

    第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的  DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...

  8. 第十一章 TClientDataSet

    第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...

  9. 第十一章、认识与学习BASH

    第十一章.认识与学习 BASH 最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 ...

随机推荐

  1. 使用 html5 postMessage 实现跨域

    英文原文 中文翻译 因为web的安全机制,浏览器的同源策略.在不同域之间做数据交换就会涉及到跨域.A域如果要实现向B域发关消息,多多少少要有对B域有一定控制权,最起码人家B域要接收你的消息啊. 最近发 ...

  2. Programs vs. processes

    Computer Systems A Programmer's Perspective Second Edition This is a good place to pause and make su ...

  3. SQL查询语句中的 limit offset(转 )

    经常用到在数据库中查询中间几条数据的需求 比如下面的sql语句: ① selete * from testtable limit 2,1; ② selete * from testtable limi ...

  4. oracle EBS 资产定义

    一.资产定义也就是江项目任务上的特定(能生成资产的)物料按照一定格式生成资产信息,其中每个独立物料生成一条资产,具体操作步骤如下: 1.省本部库存超级用户系统内生成领料单.审批领料单.最后进行出库处理 ...

  5. Python中Unicode字符串

    Python中Unicode字符串 字符串还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte ...

  6. 一个mysql开启多个端口

    在测试Mysql多主一从服务器,即一个从服务器多端口同步不同主库.本文记录了开启不同端口的操作. 详细步骤: 1.首先要先把my.cnf配置文件复制一份,开几个端口要复制几份当然要重新命名. 如: c ...

  7. 【转】MySQL USE NAMES 'UTF8'

    先说MySQL的字符集问题.Windows下可通过修改my.ini内的 # CLIENT SECTION [mysql] default-character-set=utf8 # SERVER SEC ...

  8. rpc rmi http

    1.RPC与RMI (1)RPC 跨语言,而 RMI只支持Java. (2)RMI 调用远程对象方法,允许方法返回 Java 对象以及基本数据类型,而RPC 不支持对象的概念,传送到 RPC 服务的消 ...

  9. Qt持久性对象进行序列化

    Mfc和Java中自定义类的对象都可以对其进行持久性保存,Qt持久性对象进行序列化当然也是必不可少的.不过这个问题还真困扰了我很长时间……Mfc通过重写虚函数Serialize().Java则是所属的 ...

  10. copy构造函数的秘密

    1.先来看这段代码: MyString::MyString(){ this->mstr = NULL;} MyString::MyString(MyString &str){ //用一个 ...