《c++ primer笔记》第十一章 关联容器
创始人
2025-05-31 13:36:18
0

前言

关联容器和顺序容器的许多操作都很类似,本章主要简单介绍了4种关联容器,包括如何定义、操作关联容器,内部原理也有简单涉及。

文章目录

    • 一、关联容器
      • 1.1定义关联容器
      • 1.2关联容器操作
      • 1.3无序容器

一、关联容器

​ 关联容器支持高效的关键字查找和访问,两个主要的关联容器类型是mapset。标准库提供8个关联容器,它们的不同有三点:1)set或者map;2)关键字是否重复;3)元素保存顺序。

image-20230316190440938

map

map类型也叫关联数组,意思它与数组类似,不同之处在于索引可以不是一个整数。类似顺序容器,关联容器也是模板

set

set是关键字的简单集合,下面是一个mapset简单使用的案例,代码的功能就是从用户输入的单词中,抛弃那些在set中出现的单词。

map word_count;
set exclude = { " The", "But", "OR"};
string word;
while(cin >> word) {if(exclude.find(word) == exclude.end())++word_count[word];
}

1.1定义关联容器

关联容器不支持顺序容器的位置相关操作,因为关联容器中元素是根据关键字存储的。同时也不接受构造函数或插入操作这些接受一个元素值和一个数量值的操作。关联容器的迭代器都是双向的

​ 每个关联容器都定义了一个默认构造函数,它创建一个指定类型的空容器。

map word_count; // 默认初始化
set exclude = { " The", "But", "OR"};
map word_count = { {"1", 1} ,{"2", 2} ,{"3", 3}}; // 列表初始化

初始化mutimap或multiset

​ 一个mapset中的关键字必须是唯一的,对于multimapmultiset没有限制。

vec; // 含有20个数字,0-9 重复一次
set s(vec.begin(), vec.end()); // 10
multiset mset(vec.begin(), vec.end()); // 20

关键字类型的要求

​ 前面提到有些算法比如sort的比较操作我们可以自定义,类似地,我们也可以在有序关联容器上定义比较操作。注意所提供的比较操作在关键字类型上定义一个严格弱序(小于等于)。规则就是不能出现两个一模一样的关键字。下面是一个案例,第一行代码是错误的,因为我们假如MyClass并没有<运算符,当我们有一个自定义的比较函数cmp,我们就可以在定义multiset时加入比较函数的指针类型

mutiset; // 错误
mutiset;

pair类型

pair定义在头文件utilty中,一个pair保存两个数据成员。pair的默认构造函数对数据成员进行值初始化。

pair anon;
pair word_count;
pair> line;

pair的数据成员是public的,分别为firstsecond

image-20230316194815811

创建pair对象的函数

pair process(vector &v) {if(!v.empty())return {v.back(), v.back().size()}; // 列表初始化,早期C++版本只允许显示构造返回值 pair(v.back, v.back.size())elsereturn pair(); // 隐式构造返回值
}

1.2关联容器操作

​ 对于set类型,key_typevalue_type是一样的,set中保存的值就是关键字。在map中,每个元素都是是一个pair对象,包含一个关键字和一个关联的值。由于不能改变一个元素的关键字,因此这些pair的关键字部分是const的。

image-20230316195516720

set::value_type v1; // string
set::key_type v2; // string
map::value_type v3; // pair
map::key_type v4; //string
map::mapped_type v5;  // int

​ 解引用一个关联容器迭代器时,会得到一个类型为容器的value_type的引用。

auto map_it = word_count.begin();
cout << map_it->first; // 指向关键字
map_it->first = "new key"; // 错误,关键字时const

set的迭代器是const

set iset = {0,1,2,4,5,,6,6};
set::iterator set_it = iset.begin();
if(set_it != iset.end()) {*set_it = 42; // 错误,set中的关键字为只读cout << *set_it << endl;
}

关联容器和算法

​ 一般不对关联容器使用泛型算法,因为关键字的类型为const。当然,对于一些只读元素的算法关联容器是适用的,但是这类算法都要搜索序列,而关联容器中的元素不能通过它们的关键字进行查询(没太懂)。

添加元素

insert向容器中添加一个元素或一个范围,即使添加的元素已经存在也不会对容器造成影响。

vector ivec = {2,4,5,6,7,8};
set set2;
set2.insert(ivec.begin(), ivec.end()); //{2,4,5,6,7,8}
set.inster({{2,4,5,6,7,8}}); //{2,4,5,6,7,8}

对一个map进行insert操作时,必须记住元素的类型是pair

word_count.insert({word, 1});
word_count.insert(make_pair(word,1));
word_count.insert(pair(word, 1));
word_count.insert(pair::value_type(word, 1));

image-20230316203559824

检测insert的返回值

​ 对于不包含重复关键字的容器,添加单一元素的insertemplace版本返回一个pairfirst是一个迭代器,指向具有关键字的元素;second是一个bool值,指出元素是否插入成功。

​ 对允许重复关键字的容器,接受单个元素的insert操作返回一个指向新元素的迭代器。

删除元素

​ 关联容器有三个版本的erase。对于不重复的容器,返回值总是0或1;允许重复的容器删除元素的数量可能大于1。

image-20230320104603102

map的下标操作

mapunordered_map容器都提供了下标运算符和一个对应的at函数。set不支持下标,因为set没有与关键字相关联的值。map可以像数组一样使用[]获取关键字对应的值,值得注意的是,如果原map中没有这个关键字,则会将当前关键字存入map,对应的值会进行值初始化

image-20230320110424001

map的下标运算符的返回类型是一个mapped_type对象,解引用一个map迭代器会得到一个value_type对象。

访问元素

image-20230320111013911

1.3无序容器

​ 无序容器在存储组织上为一组桶,每个桶保存零个或多个元素。容器将具有一个特定哈希值的所有元素都保存在相同的桶中,无序容器的性能依赖于哈希函数的质量和桶的数量和大小。

image-20230320122609586

相关内容

热门资讯

走进小城看消费丨江西资溪:低碳...   夏日时节下午4点,江西省抚州市资溪县大觉山景区漂流终点依然热闹。来自南昌的游客余鑫漂流结束后没有...
【中原晨会0625】市场分析专... 来源:市场资讯 (来源:中原证券研究所) 本期重点研报目录 【中原策略】市场分析:电子半导体领涨 ...
南向资金连买4日!低费率+可月... 6月25日早盘,港股红利资产震荡整理。截至11时14分,港股红利低波ETF招商(520550)下跌0...
618成交破百万!紫荆花用一套... 一年一度的618年中大促,是消费市场的晴雨表,也是品牌间最激烈的角力场。当各大品牌在直播间里铆足了劲...
原创 黄... 2026年6月25日的国际金价已经从前期的5500美元高点跌到4200美元下方,累计跌幅超过22%,...
英伟达CEO:Vera Rub... 截至9:38,中证半导体材料设备主题指数(931743)涨2.36%创新高;权重股中,中微公司涨3....
再被催债16亿!“钢铁大王”戴... 澎湃新闻记者 贺梨萍 因“铁本事件”入狱五年的戴国芳重返钢铁行业,但他并没有完成从阶下囚再到“钢铁大...
周三原油价格下跌 随着美国和伊朗在和平谈判中取得进展,越来越多的油轮公开穿越霍尔木兹海峡,原油在战时的价格上涨已经蒸发...
这种蛋白是大脑衰老的开关 这种蛋白是大脑衰老的开关 清晨,假设一位五十岁左右的王女士发现自己常常把手机放在熟悉的抽屉里又找不到...
信通院牵头算力Token出海生... 盘面上,截至11:04,中证科创创业50指数(931643)涨1.68%,创历史新高;权重股中,芯原...
海外 774 亿营收背后:日本... 文 | 游戏价值论 6月23日,彭博社报道了腾讯正在围绕出售多家日本游戏工作室少数股权开展谈判,包...
餐饮“抢人”大战:把店开到公交... 作者 |餐饮老板内参 内参君 医院、公交站、演唱会…餐饮品牌,正在无孔不入 在北京儿童医院,肯德基...
快讯 | 外资扫货!陈翊庭:港... 港交所行政总裁陈翊庭在接受《中国证券报》专访时指出,国际资本对中国资产的看法已彻底扭转,布局中国市场...
2777.77元!A股“股王”... 25日早盘,昨天创下历史新高的A股“股王”联讯仪器,今天上午继续走强,盘中股价再度刷新历史新高。 截...
原创 今... 欧洲自己的媒体直接下结论,欧盟衰退躲不掉,内部分裂拦不住,现在就连欧洲顶尖工业巨头,都偷偷在用中国的...
黄仁勋股东大会放言:本轮AI基... 在当地时间6月24日的英伟达(NVDA.O)2026年度股东大会上,股东批准了该公司全部10名董事会...
国际油价大跌 新华社消息, 纽约原油期货主力合约价格24日盘中跌破每桶70美元,为伊朗战事爆发以来首次。 市场分析...
马云带队插秧,什么信号? 一场别开生面的“务农”,让外界看到了一个不一样的阿里巴巴。 近日,阿里巴巴合伙人、高德董事长刘振飞在...
全球最大产能,最高丰度达99.... 本文转自【科技日报】; 6月23日,高丰度硼-10同位素技术暨产业化成果发布会在山东省东营市举办,全...
黄金大跳水!金饰克价年内暴跌近... 25日,现货黄金盘中震荡,截至发稿,报3985.070美元/盎司,跌0.17%。 当地时间24日,...