C++Primer读书笔记(第十章)

第十章关联容器

         关联容器支持通过键来高效地查找和读取元素。

10.1 引言:pair类型

         pair类型在utility头文件中定义。pair包含两个数值,也是一种模板类型,在创建pair对象时,必须提供两个类型名:pair对象所包含的两个数据成员各自对应的类型名字,这两个类型不必相同。

创建pair类型

pair<T1, T2> p1

创建一个空的pair对象,两个元素分别是T1类型和T2类型,采用值初始化

pair<T1, T2> p1(v1, v2)

创建一个pair对象,并且first成员初始化为v1,second成员初始化为v2

生成新的pair对象

make_pair(v1, v2)

以v1和v2值创建一个新的pair对象,元素类型分别是v1和v2的类型

访问pair数据成员

p.first

返回first成员

p.second

返回second成员

pair对象关系运算

p1 < p2

遵循字典次序

p1 == p2

pair对象的first和second成员依次相等

10.2 关联容器

         关联容器共享了大部分顺序容器的操作,但不提供front、push_front、pop_front、back、push_back以及pop_back操作。

10.3 map类型

         必须包含map头文件:#include<map>

10.3.1 map对象的定义

         map是键-值对的集合,map类型通常可理解为关联数组。定义map对象时,必须指明键和值的类型:

         map<string,int> word_count;         //键的类型是string,关联值的类型是int

map<k, v> m;

创建一个名为m的空map对象

map<k, v> m(m2);

创建m2的副本m,m与m2必须有相同的键值类型

map<k, v> m(b, e);

创建map类型的对象m,存储迭代器b和e范围内的所有元素的副本,b和e必须是指向pair类型的迭代器

         键的类型必须定义 <操作符,也是唯一约束,而且该操作符应能正确工作,比较函数必须在键类型上定义严格弱排序。因为关联容器中元素是按顺序(键排序)存储的。

10.3.2 map定义的类型

map<K, V>::key_type

用作索引的键的类型

map<K, V>::mapped_type

键所关联的值的类型

map<K, V>::value_type

一个pair类型,它first元素是const key_value类型,不可修改,second元素是mapped_type

10.3.3 给map添加元素

         给容器添加键-值元素对,可以使用insert实现,或者使用下标操作。

10.3.4 使用下标访问map对象

         map<string,int>  word_count;

         word_count[“Anna”]= 1;         //原容器中不存在”Anna”键,将添加新pair对象作为元素

使用下标访问map与使用下标访问数组或vector的行为截然不同:下标访问不存在的元素将导致在map容器中添加一个新的元素,键为下标值。下标存在的话与数组操作类似。map迭代器返回的是value_type类型,是一个pair对象。下标操作符返回一个mapped_type类型。

10.3.5 map::insert的使用

m.insert(e)

e是一个m上的value_type类型的值。如果键e.first不存在,则插入元素e;如果键已存在,则保持m不变。

函数返回一个pair类型对象,分别包含指向键为e.first的元素的map迭代器,以及一个bool类型的对象,表示是否插入了该元素

m.insert(beg, end)

beg和end是标记元素范围的迭代器,其中的严肃必须为m.value_type类型。返回void类型

m.insert(iter, e)

如果键e.first不在m中,则创建新元素,并以迭代器iter为起点搜索新元素存储的位置。返回一个迭代器,指向m中具有给定键的元素

         pair<map<string,int>::iterator, bool>  ret =word_count.insert(make_pair(word, 1));

10.3.6 查找并读取map元素

m.count(k)

返回m中k的出现次数

m.find(k)

如果m中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端的迭代器

10.3.7 从map对象中删除元素

m.erase(k)

删除m中键为k的元素,返回size_type类型的值,表示删除的元素个数。若不存在,则返回0。map容器必然是0或1

m.erase(k)

删除迭代器p所指向的元素,p必须指向m中确实存在的元素,并且不能等于m.end()。返回void类型

m.erase(b, e)

删除迭代器b和e范围内的元素。返回void类型

10.3.8 map对象的迭代遍历

         map同样提供begin和end运算。

         map<string,int>::const_iterator  map_it =word_count.begin();

10.3.9 “单词转换”map对象

         程序示例。

10.4 set类型

         set容器只是单纯的键的集合,不支持下标操作,且没有定义mapped_type类型,其key_type与value_type都是键类型。

         必须包含头文件:#include<set>

10.4.1 set容器的定义与使用

         set容器的每个键都只能对应一个元素,类似数学的集合概念。

         set<string>  set1;           //定义一个空的set容器

set<int>  iset(ivec.begin(), ivec.end() );                  //定义并初始化iset容器,并且用vector

类型对象ivec的元素初始化,注意的是对于每个键,只添加一次元素

set1.insert(“the”);            //插入键,返回一个pair类型对象:一个指向拥有该键的元素的迭代器和一个表示是否添加成功的bool值

iset.insert( ivec2.begin(), ivec2.end() );            //插入一组元素,返回void

iset.find(11);             //返回指向该元素的迭代器,否则返回iset.end()

iset.count(11);          //返回个数0或1

set中的键也是const,不能修改,获取迭代器后只能读取,不能写入。

10.4.2 创建“单词排除”集

         程序示例。

10.5 multimap和multiset类型

         multimap和multiset类型允许一个键对于多个实例。multimap类型不支持下标操作。

         头文件分别为<map>和<set>。

10.5.1 元素的添加和删除

         每次insert都会添加一个元素。

         带有一个键参数的erase版本将删除拥有该键的所有元素,并返回size_type类型,删除元素的个数。而带有一个或一对迭代器参数的版本只删除指定的元素,并返回void类型。

10.5.2 在multimap和multiset中查找元素

         map和set的元素时按顺序存储的,multimap和multiset也是如此。因此,在multimap和multiset中,如果某个键对应多个实例,则这些实例在容器中将相邻存放。

         要求输出某个键对应的所有元素,有3个策略:

         (1)使用find和count操作

         count返回某键出现次数,find返回指向第一个拥有查找元素的迭代器。循环就可以实现输出所有相应元素。

         (2)使用特别的迭代器操作

m.lower_bound(k)

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

m.upper_bound(k)

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

m.equal_range(k)

返回一个pair对象,第一个元素时m.lower_bound(k),第二个元素是m.upper_bound(k)

         multimap<string,string>  authors;

typedef  multimap<string, string>::iterator  authors_it;

         authors_it  beg = authors.lower_bound(serach_item);

         authors_it  end = authors. upper_bound(serach_item);

         while(beg != end) {

                   cout<< beg -> second << endl;

                   ++beg;

         }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿清陪你聊聊数据分析

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值