C++关联容器之map

1.map简介

  map中的元素是关键字-值对:关键字起到索引的作用,值表示与索引相关的数据。我们常用的字典就是很好的map的实例,单词作为索引,其中文含义代表其值。map类型通常被称为关联数组,其和数组很相似,只不过其下标不是整数而是关键

,我们通过关键字来查找值而不是位置。比如电话簿也是一个map的例子,姓名作为关键字其对应的值就为该人的电话号码。map类型定义在头文件map中

注意:map是有序的且不允许重复关键字的关联容器!其有序的实现是依靠关键字类型中的"<"来实现的。

 

2.map的定义与初始化

  2.1 创建空map

map<key_type,value_type> tempMap;//创建空map

  2.2 列表初始化map

map<key_type,value_type> tempMap{
  {key1,value1},
  {key2,value2},
  ......};

  2.3 使用已有的map复制构造

map<key_type,value_type> tempMap(existMap);//注意关键字类型与值类型匹配

   2.4  指定已有map的迭代器返回进行构造

map<key_type,value_type> tempMap(b,e);//b,e为已有map对象的迭代器范围

 

3.map的赋值操作

  我们可以将一个已有的map赋值给另一个map:

map1=map2;

map也支持列表赋值:

map<key_type,value_type> tempMap={
  {key1,value1},
  {key2,value2},
  ......};

 

4.关联容器额外的类型别名

  除了之前的容器操作具有的类型,map有自己独特的类型别名:

类型别名

说明

key_type

关键字类型

 mapped_type

关键字关联的类型

 value_type

pair<const key_type,mapped_type>

举例

map<int ,string> myMap;
myMap::value_type v1;//v1为pair<const int ,string>类型
myMap::key_type v2;//v2为int类型
myMap::mapped_type v3;//v3为string类型

 

5. 新的数据类型  pair类型

  pair标准类型定义在头文件utility中,一个pair保存两个数据成员,pair是用来生成特定类型的模板,当创建一个pair对象时必须要提供两个类型名

pair<string string> A;//保存两个string
pair<string ,size_t> B;//保存一个string,一个size_t
pair<int ,vector<int>> C;//保存一个int和vector<int>

上面的代码都是执行了默认构造函数来对数据成员进行初始化,我们也可以初始化器:

pair<string,string> thePair{"Hello","World"};

pair的数据成员是public的,并且成员命名为first和second,我们可以使用普通的成员访问符“.”来进行访问。

  我们可以在pair上的操作如下:

操作 

说明

pair<T1,T2> P;

p的成员数据类型分别为T1,T2,并执行默认初始化

pair<T1,T2> p(v1,v2);

P的成员数据类型分别为T1,T2,并且使用v1,v2分别初始化

pair<T1,T2> p={v1,v2};

等价于上式

make_pair(v1,v2);

返回一个v1和v2初始化的pair,其类型由v1和v2推断而来

p.first

返回p的first成员

 p.second

返回p的second成员

 p1 relop p2

执行关系运算(>,<,<=,>=),利用数据类型中的关系运算

 p1==p2

相等性判断,必须first和second同时满足要求

p1!=p2 

不等于判断

 

5.1 创建使用pair对象的函数

pair<int ,string> do_something(vecotr<string> &v)
{

    if(!v.empty())
    {
       return {v.back().size(),v.back()}; 
    }
    else
    {
       return pair<int ,string>();    
    }    

}

有些较早版本的编译器不支持花括号返回,那我们可以先构造pair对象再返回

pair<int ,string> do_something(vecotr<string> &v)
{

    if(!v.empty())
    {
       return pair<int ,string>(v.back().size(),v.back());//也可使用make_pair来生成pair对象
   }
else { return pair<int ,string>(); } }

 

6.map的迭代器

  当我们对map的迭代器进行解引用的时候我们得到的是value_type类型,也就是一个pair类型,要注意的是其first成员是const的,second成员是非常量成员,很明显我们不能改变map关键字,但我们可以改变关键字所关联的值,我们可以使用迭代器来遍历我们的map对象

auto map_iter=myMap.cbegin();
while(map_iter!=myMap.cend())
{
      cout<<"key: "<<map_iter->first<<"value: "<<map_iter->second<<endl;
      
       ++map_iter; 
}    

  注意:由于map中的关键字是const,我们一般不对map使用泛型算法!

 

7.向map添加元素

  我们使用insert对map进行元素添加操作,我们必须要记住的一点就是map的元素是pair类型的,下面列举常用的insert方法:

myMap.insert({k1,v1});
myMap.insert(make_pair(k2,v2));
myMap.insert(pair<key_type,value_type>(k3,v3));
myMap.insert(map<key_type,value_type>::value_type(k4,v4));

下面列举其他的一些添加元素的方式:

操作

说明

c.insert(v)

v为value_type对象,返回一个pair包含一个迭代器和是否成功插入的bool值,关键词不存在才插入

c.emplace(args)

args用来构造元素,返回一个pair包含一个迭代器和是否成功插入的bool值,关键词不在才插入

c.insert(b,e)

b和e是迭代器,指定多个元素插入,返回void

c.insert(il)  

il花括号列表形式,返回void

c.insert(p.v)

和insert(v)类似,p是迭代器,指定从哪里开始搜索新元素应该存储的位置,返回值为一个迭代器,指出具有给定关键字的元素

c.emplace(p,args)

和c.emplace(args)类似,p是迭代器,指定从哪里开始搜索新元素应该存储的位置,返回值为一个迭代器,指出具有给定关键字的元素

 7.1 检测insert的返回值

   添加单一元素的insert和emplace返回值一个pair,告诉我们插入是否成功,pair的first是一个迭代器,指向具有给定关键字的元素,second是一个bool型,如果插入成功为true,否则为false。如果关键字已经在map中那么insert和emplace什么也不做。

 

8.删除元素

  使用erase函数来执行map的删除操作:

操作

说明

c.erase(k)

删除c中关键词为k的元素,返回值为size_type类型,指出删除元素的数目,因为map中不允许重复,返回值为0或者1

c.erase(p)

从c中删除迭代器p指定的元素,p必须指向一个真实存在的元素,返回值指向p之后元素的迭代器,如果p指向c的微元素,那么将返回c.end()

 c.erase(b,e)

删除迭代器对b和e所表示返回的元素,返回值迭代器e 

 

9. map的下标操作

  map提供了下标操作和at函数操作。我们对map使用下标操作要注意下标是关键字,还要注意的是对不存在map中的关键字使用了下标操作,会添加一个具有该关键字的元素到map中。

操作

说明

c[k]

返回关键字为k的元素,如果k不在c中,添加一个关键字为k的元素,对其进行初始化

c.at(k)

访问关键字为k的元素,带参数检查,如果k不在c中,则返回out_of_range异常

9.1使用下标操作的返回值

   当我们对一个map进行下标操作的时候,会获得mapped_type对象,但当解引用map的迭代器时,会得到一个value_type对象,如果关键字不存在map中,下标运算依然会添加一个具有该关键字的新元素。在我们不确定一个元素是否在map中,且不想在map中进行添加就不能使用下标操作。

 

10.访问元素

  当我们要确定一个元素是否存在map中,使用find是最佳的选择,对于不允许重复关键字的map来说,使用count函数返回的关键字计数只能为0和1。对于map元素的访问还有如下的操作:

操作  

说明

c.find(k)

返回一个迭代器,指向第一个关键字为k的元素,如果不在map中,则返回尾后迭代器c.end()

c.count(k)

返回关键字等于k的元素数量,对于map返回值只能为0和1

c.lower_bound(k)

返回一个迭代器,指向第一个关键字不小于k的元素

c.upper_bound(k)

返回一个迭代器,指向第一个关键字大于k的元素

c.equal_range(k)

返回一个迭代器pair,表示关键字等于k元素的范围,如果k不存在,则pair的数据成员全是c.end()

备注:如果使用lower_bound和upper_bound匹配关键字k,返回了相同的迭代器,那么关键字k不在map中。

  

 

posted on 2017-09-02 17:55  CodeBeauty  阅读(5288)  评论(0编辑  收藏  举报

导航