c++ primer 学习笔记19 map容器

10.3.2.map 定义的类型


map 接口的value_type 是 pair 类型,它的值成员可以修改,但键成员不能修改。

map 迭代器进行解引用将产生 pair类型的对象

对迭代器进行解引用时,将获得一个引用,指向容器中一个 value_type 类型的值。对于 map 容器,其 value_type 是 pair 类型。

10.3.4.使用下标访问 map 对象

如下编写程序时:

    map <string, int> word_count; // empty map

     // insert default initialzed element withkey Anna; then assign 1 to its value

    word_count["Anna"] = 1;

使用下标访问 map 与使用下标访问数组或 vector 的行为截然不同:用下标访问不存在的元素将导致在 map 容器中添加一个新元素,它的键即为该下标值。

如同其他下标操作符一样,map 的下标也使用索引(其实就是键)来获取该键所关联的值。如果该键已在容器中,则 map 的下标运算与 vector 的下标运算行为相同:返回该键所关联的值。只有在所查找的键不存在时,map 容器才为该键创建一个新的元素,并将它插入到此map 对象中。此时,所关联的值采用值初始化:类类型的元素用默认构造函数初始化,而内置类型的元素初始化为 0。

10.3.5.map::insert 的使用

map 容器的 insert 成员与顺序容器的类似,但有一点要注意:必须考虑键的作用。键影响了实参的类型:插入单个元素的 insert 版本使用键-值 pair类型的参数。类似地,对于参数为一对迭代器的版本,迭代器必须指向键-值pair 类型的元素。另一个差别则是:map 容器的接受单个值的 insert 版本的返回类型。


以 insert 代替下标运算

使用下标给 map 容器添加新元素时,元素的值部分将采用值初始化。通常,我们会立即为其赋值,其实就是对同一个对象进行初始化并赋值。而插入元素的另一个方法是:直接使用 insert 成员,其语法更紧凑:

     // if Anna not already inword_count, inserts new element with value 1

     word_count.insert(map<string,int>::value_type("Anna", 1));

这个 insert 函数版本的实参:

     map<string,int>::value_type(anna, 1)

使用 insert 成员可避免使用下标操作符所带来的副作用:不必要的初始化。

传递给 insert 的实参相当笨拙。可用两种方法简化:使用 make_pair:

    word_count.insert(make_pair("Anna", 1));

或使用 typedef

     typedefmap<string,int>::value_type valType;

    word_count.insert(valType("Anna", 1));

检测 insert 的返回值

map 对象中一个给定键只对应一个元素。如果试图插入的元素所对应的键已在容器中,则 insert 将不做任何操作。含有一个或一对迭代器形参的 insert函数版本并不说明是否有或有多少个元素插入到容器中。

但是,带有一个键-值 pair 形参的 insert 版本将返回一个值:包含一个迭代器和一个 bool 值的 pair 对象,其中迭代器指向 map 中具有相应键的元素,而 bool 值则表示是否插入了该元素。如果该键已在容器中,则其关联的值保持不变,返回的 bool 值为 true。在这两种情况下,迭代器都将指向具有给定键的元素。

10.3.6.查找并读取 map 中的元素

下标操作符给出了读取一个值的最简单方法:

     map<string,int>word_count;

     int occurs =word_count["foobar"];

但是,使用下标存在一个很危险的副作用:如果该键不在 map 容器中,那么下标操作会插入一个具有该键的新元素。

这样的行为是否正确取决于程序员的意愿。在这个例子中,如果“foobar”不存在,则在 map 中插入具有该键的新元素,其关联的值为 0。在这种情况下,occurs 获得 0 值。

map 容器提供了两个操作:count 和 find,用于检查某个键是否存在而不会插入该键。



使用 count 检查 map 对象中某键是否存在

对于 map 对象,count 成员的返回值只能是 0 或 1。map 容器只允许一个键对应一个实例,所以 count 可有效地表明一个键是否存在。

int occurs = 0;

     if(word_count.count("foobar"))

         occurs =word_count["foobar"];

 

当然,在执行 count 后再使用下标操作符,实际上是对元素作了两次查找。如果希望当元素存在时就使用它,则应该用 find 操作。

读取元素而不插入该元素

find 操作返回指向元素的迭代器,如果元素不存在,则返回end 迭代器:

     int occurs = 0;

    map<string,int>::iterator it =word_count.find("foobar");

     if (it != word_count.end())

         occurs =it->second;

10.3.7.从 map 对象中删除元素

从 map 容器中删除元素的 erase 操作有三种变化形式(表 10.7)。与顺序容器一样,可向 erase 传递一个或一对迭代器,来删除单个元素或一段范围内的元素。其删除功能类似于顺序容器,但有一点不同:map 容器的 erase 操作返回 void,而顺序容器的 erase 操作则返回一个迭代器,指向被删除元素后面的元素。


10.3.8.map 对象的迭代遍历

与其他容器一样,map 同样提供 begin 和 end 运算,以生成用于遍历整个容器的迭代器。例如,可如下将 map 容器 word_count 的内容输出:

 

  // get iterator positioned on the first element 
     map<string, int>::const_iterator 
                             map_it = word_count.begin(); 
     // for each element in the map 
     while (map_it != word_count.end()) { 
         // print the element key, value pairs 
         cout << map_it->first << " occurs " 
              << map_it->second << " times" << endl; 
         ++map_it; // increment iterator to denote the next element 
     }

 







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值