STL提供了4个关联容器:set、multiset、map和multimap。这些容器提供了通过keyword高速存储和訪问数据元素的能力。Set和map不同意有反复keyword,而multiset和multimap同意反复keyword。关联容器的几个共同函数例如以下:

find(key):搜索容器中具有指定keyword的元素,返回指向此元素的迭代器。

lower_bound(key):搜索容器中具有指定keyword的第一个元素。返回指向此元素的迭代器。

upper_bound(key):搜索容器中具有指定keyword的最后一个元素,返回指向此元素的迭代器。

count(key):返回容器中具有指定keyword的元素的数目。

Map是比較重要的STL容器。本文主要来介绍map的原理和一些常见的使用方法。

1.map实现的原理

Map内部自建一个一颗红黑树,一种严格意义上的平衡二叉树,这颗树具有对数据自己主动排序的功能。所以在map内部全部的数据都是有序的。

2.数据插入

1)用insert函数插入pair数据。

2)用insert函数插入value_type数据。

3)用数组方式插入数据。

以上三种方法,都能够实现插入操作,可是还是有差别的。用insert函数进行插入操作时,在数据的插入上涉及到集合的唯一性这个概念,即当map中有key值时。insert操作无法插入数据。可是假设是用数组方式就不同了,它能够覆盖曾经keyword相应的值。能够用pair来获得是否插入成功,Pair<map<int, string>::iterator, bool> Insert_Pair,运行完insert操作后。通过推断Insert_Pair.second值的真假来推断是否插入成功。

代码举例及分析例如以下:

#include <iostream>
#include <map>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
map<int,string> map1;
map1.insert(pair<int,string>(1,"John")); //insert pair的方式插入
map1.insert(pair<int,string>(1,"Jeff")); //不会再运行插入操作
map1.insert(map<int,string>::value_type(2,"King")); //insert value_type的方式插入
map1.insert(map<int,string>::value_type(2,"Jane")); //不会再运行插入操作
map1[3]="Peter"; //数组方式插入
map1[3]="Smith"; //会覆盖掉上一个值
map<int,string>::iterator p; //迭代器遍历输出
for(p=map1.begin();p!=map1.end();p++)
{
cout<<p->first<<"\t"<<p->second<<endl;
}
pair<map<int, string>::iterator, bool> insert_pair; //用pair推断是否成功插入数据
insert_pair=map1.insert(pair<int,string>(4,"Kevin"));
if(insert_pair.second) //推断是否插入成功
{
cout<<"Insert Kevin Successfully"<<endl;
}
else
{
cout<<"Insert Kevin failed"<<endl;
}
insert_pair=map1.insert(pair<int,string>(4,"Cathy"));
if(insert_pair.second)
{
cout<<"Insert Cathy Successfully"<<endl;
}
else
{
cout<<"Insert Cathy failed"<<endl;
}
for(p=map1.begin();p!=map1.end();p++)
{
cout<<p->first<<"\t"<<p->second<<endl;
}
return 0;
}

运行结果为:

1 John

2 King

3 Smith

Insert Kevin Successfully

Insert Cathy failed

1 John

2 King

3 Smith

4 Kevin



3.数据遍历

1)应用前向迭代器

2)应用反向迭代器

3)用数组方式

代码及分析例如以下:

#include <iostream>
#include <map>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
map<int,string> map1;
map1.insert(pair<int,string>(1,"John"));
map1.insert(pair<int,string>(2,"Jeff"));
map1.insert(pair<int,string>(3,"Smith"));
map<int,string>::iterator it; //前向迭代器遍历输出
cout<<"应用前向迭代器输出:"<<endl;
for(it=map1.begin();it!=map1.end();it++)
{
cout<<it->first<<"\t"<<it->second<<endl;
}
map<int,string>::reverse_iterator reverse_it; //反序迭代器
cout<<"应用反向迭代器输出:"<<endl;
for(reverse_it=map1.rbegin();reverse_it!=map1.rend();reverse_it++)
{
cout<<reverse_it->first<<"\t"<<reverse_it->second<<endl;
}
int size = map1.size();
cout<<"应用数组方法输出:"<<endl;
for(int index=1;index<=size;index++)
{
cout<<index<<"\t"<<map1[index]<<endl;
}
return 0;
}

运行结果为:

应用前向迭代器输出:

1 John

2 Jeff

3 Smith

应用反向迭代器输出:

3 Smith

2 Jeff

1 John

应用数组方法输出:

1 John

2 Jeff

3 Smith



4.数据查找

1)用count函数推断keyword是否出现,它的缺点是不能定位keyword的位置。

2)用find函数。它会返回一个迭代器,假设查找到数据,则返回数据所在位置的迭代器,假设没有查找到,则返回end迭代器。

代码及分析例如以下:

#include <iostream>
#include <map>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
map<int,string> map1;
map1.insert(pair<int,string>(1,"John"));
map1.insert(pair<int,string>(2,"Jeff"));
map1.insert(pair<int,string>(3,"Smith"));
map<int,string>::iterator it; //前向迭代器遍历输出
cout<<"应用前向迭代器输出:"<<endl;
for(it=map1.begin();it!=map1.end();it++)
{
cout<<it->first<<"\t"<<it->second<<endl;
}
if (map1.count(1)!=0) //用count函数来进行查找
{
cout<<"1 is in map"<<endl;
}
else
{
cout<<"1 is not in map"<<endl;
}
if(map1.find(4)!=map1.end()) //用find函数来进行查找
{
cout<<"4 is in map"<<endl;
}
else
{
cout<<"4 is not in map"<<endl;
}
return 0;
}

运行结果为:

应用前向迭代器输出:

1 John

2 Jeff

3 Smith

1 is in map

4 is not in map



5.map使用[ ]符号注意事项

使用[ ]对map进行插入或者查找操作很便捷。可是假设map下标符运用不得当,就会造成意想不到的问题。对于map而言,并没有下标越界的概念,可是却有可能发生keyword在map中不存在的问题。假设訪问的keyword在map中并不存在,则map会自己主动生成对应的keyword。并会给定一个默认的初始值。

代码和解析例如以下:

#include <iostream>
#include <map>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
map<int,string> map1;
map1.insert(pair<int,string>(1,"John"));
map1.insert(pair<int,string>(2,"Jeff"));
map1.insert(pair<int,string>(3,"Smith"));
if (map1[4] == "Kevin") //4不存在。map会自己主动加入。并初始化值为空。即“”
{
map1[4]="Cathy";
}
map<int,string>::iterator it; //前向迭代器遍历输出
cout<<"应用前向迭代器输出:"<<endl;
for(it=map1.begin();it!=map1.end();it++)
{
cout<<it->first<<"\t"<<it->second<<endl;
}
return 0;
}

运行结果为:

应用前向迭代器输出:

1 John

2 Jeff

3 Smith

4

如输出所看到的,最后输出4的值为空。

这是由于在进行查找操作时,map自己主动加入4为keyword。且它的值为空。所以。推断语句一直不成立。最后输出仍然为空。

【STL容器学习】-关联容器与map的用法的更多相关文章

  1. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

  2. stl中顺序性容器,关联容器两者粗略解释

    什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象 ...

  3. C++学习基础四——顺序容器和关联容器

    —顺序容器:vector,list,queue1.顺序容器的常见用法: #include <vector> #include <list> #include <queue ...

  4. C++ STL 顺序容器--list + 关联容器

    list 双向链表,可以双向遍历,既指向前驱节点,又指向后继但不能随机访问任意元素,可动态增加或者减少元素,内存管理自动完成,增加任何元素都不会使迭代器失效, 删除元素时,除了指向当前被删元素的迭代器 ...

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

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

  6. iBinary C++STL模板库关联容器之map/multimap

    目录 一丶关联容器map/multimap 容器 二丶代码例子 1.map的三种插入数据的方法 3.map集合的遍历 4.验证map集合数据是否插入成功 5.map数据的查找 6.Map集合删除元素以 ...

  7. C++之容器(关联容器)

    关联容器和顺序容器的本质区别:关联容器是通过键存取和读取元素.顺序容器通过元素在容器中的位置顺序存储和访问元素.因此,关联容器不提供front.push_front.pop_front.back.pu ...

  8. Docker容器学习梳理 - 容器硬盘热扩容

    前面已介绍了docker很多知识点的操作记录,今天这里梳理下docker容器空间扩展的操作.默认情况下,物理机下创建的docker容器的空间是10G(虚拟机下创建的docker容器空间就是虚拟机的空间 ...

  9. Docker容器学习梳理 - 容器间网络通信设置(Pipework和Open vSwitch)

    自从Docker容器出现以来,容器的网络通信就一直是被关注的焦点,也是生产环境的迫切需求.容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信.下面将分别针对这两方面,对容 ...

  10. Docker容器学习梳理 - 容器时间跟宿主机时间同步

    在Docker容器创建好之后,可能会发现容器时间跟宿主机时间不一致,这就需要同步它们的时间,让容器时间跟宿主机时间保持一致.如下: 宿主机时间 [root@slave-1 ~]# date Fri M ...

随机推荐

  1. 0522 json

    一.概念 json依赖于js和xml,是一种数据交换格式,json对比xml的生成和处理要更加方便.因此在许多领域,json正逐步取代xml的使用. 二.使用 1.在JS当中 json在javascr ...

  2. simpleOS 1.0

    做了一个so simple的OS,本不好意思多说的....不过还是说下吧. 首先,买不起开发板的我没有办完完成一件事,那就是保存任务上下文,因为这个过程实际上是将寄存器的值存放到任务堆栈中去的. 而要 ...

  3. Elasticsearch之批量操作bulk

    1.bulk相当于数据库里的bash操作. 2.引入批量操作bulk,提高工作效率,你想啊,一批一批添加与一条一条添加,谁快? 3.bulk API可以帮助我们同时执行多个请求 4.bulk的格式: ...

  4. ReferenceEquals()、static Equals() 、instance Equals() 与 operator==之间的联系与区别

    当你创建一个用户自定义类型(类或结构)时,你需要给你的类型定义相等操作.C#中提供了几个不同的函数来验证两个对象是否满足“相等”的含义.public static bool ReferenceEqua ...

  5. 2018年排名前20的数据科学Python库

    Python 在解决数据科学任务和挑战方面继续处于领先地位.业已证明最有帮助的Python库,我们选择 20 多个库,因为其中一些库是相互替代的,可以解决相同的问题.因此,我们将它们放在同一个分组. ...

  6. Android嵌入式(初稿)--路漫漫其修远兮,吾将上下而求索

  7. 彻底去除Google AdMob广告

    应用中包含广告是能够理解的,但经常造成用户误点,或者广告切换时造成下载流量,就有点让人不舒服了. 以下就以Google AdMob广告为例,看怎样彻底去除他. 先分析一下Google AdMob的工作 ...

  8. DNN:windows使用 YOLO V1,V2

    本文有修改,如有疑问,请移步原文. 原文链接:  YOLO v1之总结篇(linux+windows) 此外:  YOLO-V2总结篇   Yolo9000的改进还是非常大的 由于原版的官方YOLOv ...

  9. OpenCV: kalman滤波的代码段

    序言:在我的疲劳检测工程 AviTest中!显示框为320*240,使用OpenCV的kalman滤波算法,可以实现简单的锁相追踪-实现对眼球的位置锁定. 代码如下: CvPoint Wishchin ...

  10. Mysql 之实现多字段模糊查询

    在一个table中有省,市,县,期,栋,单元,室几个字段,然后用户输入一个地址从表中的字段拼接起来进行模糊查询. 解决办法: <MySQL权威指南>中CONCAT的使用方法,在书中的对CO ...