【STL九】关联容器——map容器、multimap容器

news2025/2/27 8:24:42

【STL九】关联容器——map容器、multimap容器

  • 一、map简介
  • 二、头文件
  • 三、模板类
  • 四、map的内部结构
  • 五、成员函数
    • 1、迭代器
    • 2、元素访问
    • 3、容量
    • 4、修改操作
    • ~~5、操作~~
    • 5、查找
    • 6、查看操作
  • 六、demo
    • 1、查找find
    • 2、查找lower_bound、upper_bound
    • 3、insert、emplace() 和 emplace_hint()
  • 七、multimap

一、map简介

在这里插入图片描述

  • map 容器存储的都是 pair 对象,也就是用 pair 类模板创建的键值对。
  • key和value都必须是可复制的(copyable),可移动的(movable);
  • 在使用 map 容器存储多个键值对时,该容器会自动根据各键值对的键的大小,按照既定的规则进行排序。

默认情况下,map 容器选用std::less排序规则(其中 T 表示键的数据类型),其会根据键的大小对所有键值对做升序排序。当然,根据实际情况的需要,我们可以手动指定 map 容器的排序规则,既可以选用 STL 标准库中提供的其它排序规则(比如std::greater)

  • 对于指定的排序准则而言,key必须是可比较的(comparable)。

使用 map 容器存储的各个键值对,键的值既不能重复也不能被修改

二、头文件

#include<map>

三、模板类

template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T>>
> class map;

四、map的内部结构

  • map/multimap通常以平衡二叉树完成;(同其他关联容器)
  • map和multimap会根据元素的key自动对元素排序。
    • 这样一来,根据已知的key查找某个元素时就能够有很好的效率,
    • 而根据已知的value查找元素时,效率就很糟糕。
  • 自动排序这一性质使得map和multimap身上有一个很重要的限制:你不可以直接改变元素的key.(因为这会破坏正确次序)

要修改元素的key,必须先移除拥有该key的元素,然后插入拥有新key/value的元素。(如果value非常量,就可以修改)

在这里插入图片描述

五、成员函数

1、迭代器

成员函数功能
begin()同array容器
end()同array容器
rbegin()同array容器
rend()同array容器
cbegin()同array容器
cend()同array容器
crbegin()同array容器
crend()同array容器

2、元素访问

成员函数功能
operator[]同array容器
at(n)同array容器
front()同array容器
back()同array容器
data()同array容器

3、容量

成员函数功能
size()同array容器
max_size()同array容器
empty()同array容器
reserve同vector容器
capacity同vector容器
shrink_to_fit同vector容器

4、修改操作

成员函数功能
clear()同vector容器
insert()同vector容器
insert_or_assign(C++17)插入元素,或若键已存在则赋值给当前元素
emplace()同vector容器
emplace_hint()在本质上和 emplace() 在 map 容器中构造新键值对的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示键值对生成位置的迭代器,并作为该方法的第一个参数。
try_emplace(C++17)若键不存在则原位插入,若键存在则不做任何事
erase()同vector容器
push_back()同vector容器
emplace_back()同vector容器
pop_back()同vector容器
push_front()同vector容器
emplace_front()同vector容器
pop_front()同vector容器
resize()同vector容器
swap()同vector容器
extract(C++17)从另一容器释出结点
merge(C++17)从另一容器接合结点

5、操作

成员函数功能
merge()list容器
splice()list容器
remove(val)list容器
remove_if()list容器
reverse()list容器
unique()list容器
sort()list容器

5、查找

成员函数功能
count(key)在当前 map 容器中,查找键为 key 的键值对的个数并返回。注意,由于 map 容器中各键值对的键的值是唯一的,因此该函数的返回值最大为 1。
find(key)在 map 容器中查找键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
contains (C++20)检查容器是否含有带特定键的元素
equal_range(key)该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的键为 key 的键值对(map 容器键值对唯一,因此该范围最多包含一个键值对)。
lower_bound(key)返回一个指向当前 map 容器中第一个大于或等于 key 的键值对的双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
upper_bound(key)返回一个指向当前 map 容器中第一个大于 key 的键值对的迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。

6、查看操作

成员函数功能
key_comp返回用于比较键的函数
value_comp返回用于在value_type类型的对象中比较键的函数。

六、demo

1、查找find

  • 返回值
    指向键等于 key 的元素的迭代器。若找不到这种元素,则返回尾后(见 end() )迭代器。
#include <iostream>
#include <string>       // string
#include<map>
using namespace std;
int main() {
    // 调用构造函数 1,也就是默认构造函数
    map <string, string> mymap{
        {"小b","家在西安"},
        {"小c","家在濮阳"},
        {"小a","家在北京"},
        {"小d","没有家"},
    };
    
    cout << "i can find 小c:" << endl;

    auto ite = mymap.find("小c");
    cout << ite->first << "=" << ite->second << endl << endl;

    auto ite2 = mymap.find("c");
    if (ite2 == mymap.end())
    {
        cout << "i can not find c!" << endl;
        // cout << ite->first << "=" << ite->second << endl << endl; //找不到时输出会报错的
    }
    return 0;
}

输出

i can find 小c:
小c=家在濮阳

i can not find c!

2、查找lower_bound、upper_bound

返回值

  • lower_bound:指向首个不小于 key 的元素的迭代器。若找不到这种元素,则返回尾后迭代器
  • upper_bound:指向首个大于 key 的元素的迭代器。若找不到这种元素,则返回尾后迭代器

正常场景

#include <iostream>
#include <string>       // string
#include<map>
using namespace std;
int main() {
    // 调用构造函数 1,也就是默认构造函数
    map <string, string> mymap{
        {"小b","家在西安"},
        {"小c","家在濮阳"},
        {"小a","家在北京"},
        {"小d","没有家"},
    };
    
    //找到第一个键的值不小于 "小c" 的键值对
    auto iter = mymap.lower_bound("小c");
    cout << "lower:" << iter->first << " " << iter->second << endl;

    //找到第一个键的值大于 "小c 的键值对
    iter = mymap.upper_bound("小c");
    cout << "upper:" << iter->first << " " << iter->second << endl;
    
    return 0;
}

输出

lower:小c 家在濮阳
upper:小d 没有家

临界场景

#include <iostream>
#include <string>       // string
#include<map>
using namespace std;
int main() {
    // 调用构造函数 1,也就是默认构造函数
    map <string, string> mymap{
        {"小b","家在西安"},
        {"小c","家在濮阳"},
        {"小a","家在北京"},
        {"小d","没有家"},
    };
    
    //找到第一个键的值不小于 "小c" 的键值对
    auto iter = mymap.lower_bound("小d");
    cout << "lower:" << iter->first << " " << iter->second << endl;

    //找到第一个键的值大于 "小c 的键值对
    iter = mymap.upper_bound("小d");
    if (iter == mymap.end())
    {
        cout << "i can not find uper load 小d!" << endl;
    }

    return 0;
}

输出

lower:小d 没有家
i can not find uper load 小d!

3、insert、emplace() 和 emplace_hint()

  • insert
    insert() 方法返回的是迭代器,而不再是 pair 对象:
    • 如果插入成功,insert() 方法会返回一个指向 map 容器中已插入键值对的迭代器;
    • 如果插入失败,insert() 方法同样会返回一个迭代器,该迭代器指向 map 容器中和 val 具有相同键的那个键值对。
#include <iostream>
#include <string>       // string
#include<map>
using namespace std;
int main() {
    // 调用构造函数 1,也就是默认构造函数
    map <string, string> mymap{
        {"小b","家在西安"},
        {"小c","家在濮阳"},
        {"小a","家在北京"},
        {"小d","没有家"},
    };
    
    auto ret = mymap.insert({ "小e","家在台湾"});
    cout << "insert:" << ret.first->first << " " << ret.first->second << "=" << ret.second << endl;

    ret = mymap.insert({ "小e","家在台湾" });
    cout << "insert:" << ret.first->first << " " << ret.first->second << "=" << ret.second << endl;

    return 0;
}

输出

insert:小e 家在台湾=1
insert:小e 家在台湾=0

  • emplace
    emplace() 和 emplace_hint() 是 C++ 11 标准加入到 set 类模板中的,相比具有同样功能的 insert() 方法,完成同样的任务,emplace() 和 emplace_hint() 的效率会更高。
#include <iostream>
#include <string>       // string
#include<map>
using namespace std;
int main() {
    // 调用构造函数 1,也就是默认构造函数
    map <string, string> mymap{
        {"小b","家在西安"},
        {"小c","家在濮阳"},
        {"小a","家在北京"},
        {"小d","没有家"},
    };
    
    auto ret = mymap.emplace( "小e","家在台湾");
    cout << "emplace:" << ret.first->first << " " << ret.first->second << "=" << ret.second << endl;

    ret = mymap.emplace( "小e","家在台湾" );
    cout << "emplace:" << ret.first->first << " " << ret.first->second << "=" << ret.second << endl;

    return 0;
}

输出

emplace:小e 家在台湾=1
emplace:小e 家在台湾=0

  • emplace_hint
#include <iostream>
#include <string>       // string
#include<map>
using namespace std;
int main() {
    // 调用构造函数 1,也就是默认构造函数
    map <string, string> mymap{
        {"小b","家在西安"},
        {"小c","家在濮阳"},
        {"小a","家在北京"},
        {"小d","没有家"},
    };
    
    auto iter = mymap.emplace_hint(mymap.begin(), "小e","家在台湾");
    cout << "emplace_hint:" << iter->first << " " << iter->second << endl;

    iter = mymap.emplace_hint(mymap.begin(), "小e", "家在台湾");
    cout << "emplace_hint:" << iter->first << " " << iter->second << endl;

    return 0;
}

输出

emplace_hint:小e 家在台湾
emplace_hint:小e 家在台湾

虽然 emplace_hint() 方法指定了插入键值对的位置,但 map 容器为了保持存储键值对的有序状态,可能会移动其位置。(如下图)
在这里插入图片描述

七、multimap

map 容器的区别在于,multimap 容器中可以同时存储多(≥2)个键相同的键值对。

由于 multimap 容器可存储多个具有相同键的键值对,因此表 1 中的 lower_bound()、upper_bound()、equal_range() 以及 count() 成员方法会经常用到。

  • 模板类
multimap 容器类模板的定义如下:
template < class Key,                                   // 指定键(key)的类型
           class T,                                     // 指定值(value)的类型
           class Compare = less<Key>,                   // 指定排序规则
           class Alloc = allocator<pair<const Key,T> >  // 指定分配器对象的类型
           > class multimap;
  • demo
template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >
> class multimap;
  • demo
#include <iostream>
#include <string>       // string
#include<map>
using namespace std;
int main() {
    // 调用构造函数 1,也就是默认构造函数
    multimap <string, string> mymultimap{
        {"小b","家在西安"},
        {"小c","家在濮阳"},
        {"小a","家在北京"},
        {"小d","没有家"},
        {"小d","也没有家"},
    };

    //输出 mymultimap 容器中存储键为 'b' 的键值对的数量
    cout << mymultimap.count("小d") << endl;
    
    for (auto iter = mymultimap.begin(); iter != mymultimap.end(); ++iter) {
        cout << iter->first << " " << iter->second << endl;
    }

    return 0;
}

2
小a 家在北京
小b 家在西安
小c 家在濮阳
小d 没有家
小d 也没有家

参考:
1、C++ STL 容器库 中文文档
2、STL教程:C++ STL快速入门
3、https://www.apiref.com/cpp-zh/cpp/header.html
4、https://en.cppreference.com/w/cpp/container

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/412844.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超详细!Apache+Tomcat+mod_jk搭建负载均衡集群

目录 0.流程图&#xff1a; 1.集群环境&#xff1a; 2.Apache服务器安装httpd&#xff1a; 3.tomcat1服务器和tomcat2服务器安装jdk和Tomcat 4.tomcat1服务器和tomcat2服务器创建页面&#xff1a; 5.Apache服务器的mod_jk模块的安装&#xff1a; 6.查看是否mod_jk.so模块…

DMDSC问题测试

问题一&#xff1a;手动停止两节点&#xff0c;单独启动节点二测试 集群停库前状态&#xff0c;登录监视器查看 dmcssm INI_PATHdmcssm.ini show 节点一&#xff1a; [dmdbalocalhost ~]$ DmServiceDMSERVER stop Stopping DmServiceDMSERVER: …

Go语言开发小技巧易错点100例(六)

往期回顾&#xff1a; Go语言开发小技巧&易错点100例&#xff08;一&#xff09;Go语言开发小技巧&易错点100例&#xff08;二&#xff09;Go语言开发小技巧&易错点100例&#xff08;三&#xff09;Go语言开发小技巧&易错点100例&#xff08;四&#xff09;Go…

微信小程序开发-云开发降低资源调用次数

问题 微信小程序云开发是很方便&#xff0c;减少了后端的大量工作&#xff0c;但是&#xff01; 流量主的一点广告费&#xff0c;一不小心就全被腾讯薅走了&#xff01;当然一种办法就是使用云服务器自建后端&#xff0c;也要付费&#xff0c;没有对比过&#xff0c;不知道各…

如何在移动应用中集成美颜SDK实现人脸识别和美化功能?

随着移动应用的普及和人们对美的追求&#xff0c;美颜功能已成为很多应用的必备功能。而为了实现这样的功能&#xff0c;开发者需要使用美颜SDK。本文将从以下几个方面介绍如何在移动应用中集成美颜SDK实现人脸识别和美化功能。 一、美颜SDK的介绍 美颜SDK是一种用于美化人脸的…

应用程序接口(API)安全的入门指南

本文简单回顾了 API 的发展历史&#xff0c;其基本概念、功能、相关协议、以及使用场景&#xff0c;重点讨论了与之相关的不同安全要素、威胁、认证方法、以及十二项优秀实践。 根据有记录的历史&#xff0c;随着 Salesforce 的销售自动化解决方案的推出&#xff0c;首个 We…

缩短客户响应时间的 5 种方法

在当今竞争激烈的世界中&#xff0c;客户服务就是确保卓越的客户体验。这意味着顶级品牌必须竞争为客户提供最好的客户服务&#xff0c;而且提供最快的响应时间。 改善客户服务响应时间的 5种方法 1.使用正确的客户服务软件 客户服务软件是您可以为提高客户服务而进行的最佳投资…

手写Spring框架-前奏-注解与自定义注解

目录 注解 介绍 功能 分类 注解处理器类库 自定义注解 常用元注解 自定义 注解 介绍 提供一种为程序元素设置元数据的方法用来将任何的信息或元数据&#xff08;metadata&#xff09;与程序元素&#xff08;类、方法、成员变量等&#xff09;进行关联元数据是指数据的…

游戏工厂:AICG/ChatGPT与流程式游戏开发(码客 卢益贵)

关键词&#xff1a;AI&#xff08;AICG、ChatGPT、文心一言&#xff09;、流程式管理、好莱坞电影流程、电影工厂、游戏工厂、游戏开发流程、游戏架构、模块化开发 一、前言 开发周期长、人工成本高、成功率低等是游戏公司融资困难的罪因。所以有的公司凭一个爆款游戏一骑绝尘…

【MySQL】MySQL索引优化——从原理分析到实践对比

目录 使用TRACE分析MySQL优化 开启TRACE TRACE 结果集 ORDER BY & GROUP BY 优化 优化方式 分页优化 不同场景的优化方式 JOIN关联优化 算法介绍 优化方式 COUNT优化 优化方式 使用TRACE分析MySQL优化 某些情况下&#xff0c;MySQL是否走索引是不确定的[,,_,,…

给word文档中的公式标号

给word文档中的公式标号 首先编写一个公式 cosθa2b2−c22abcos\theta\frac{a^2b^2-c^2}{2ab} cosθ2aba2b2−c2​ 在公式的最后&#xff08;不要超出公式块&#xff09;输入#()并按回车&#xff1a; 即可在生成的框中输入公式序号&#xff1a;

Sobel 算子

1、简介 SobelSobelSobel 本质是基于图像空间域卷积&#xff0c;卷积的作用除了实现图像模糊或者去噪&#xff0c;还可以寻找一张图像上所有梯度信息&#xff0c;这些梯度信息是图像的最原始特征数据&#xff0c;进一步处理之后就可以生成一些比较高级的特征用来表示一张图像实…

快速搭建第一个SpringCloud程序

目录 1、Spring Boot项目脚手架快速搭建 1.1 生成工程基本配置 1.2 生成工程。 1.3 导入开发工具&#xff08;此处为Idea&#xff09; 1.4 运行代码 1.5 验证是否能访问 2、Spring Cloud环境搭建 2.1 版本匹配问题 2.2 Spring Cloud环境测试 3、引入Eureka Server 3…

《GPT-4技术报告》【中文版、英文版下载】

大预言模型时代已经到来&#xff0c;但是真正的智能之路还很长。 一、以下是连接&#xff0c;大家请自取。 英文原版&#xff1a;https://arxiv.org/pdf/2303.08774.pdfhttps://arxiv.org/pdf/2303.08774.pdf 中文翻译版本&#xff1a; 人工通用智能的星星之火:GPT-4的早期实…

【Linux】vi编辑器——命令模式

目录 行复制&#xff08; "yy") 示例&#xff1a; 结果&#xff1a; 粘贴 多行复制&#xff08;"nyy") 示例&#xff1a; 结果&#xff1a; 行间跳转 1G或gg-------------------跳转到文本内容的第一行 示例&#xff1a; 结果: G-----------…

刷题日记①

day01 1. %m.ns 打印输出 以下程序的运行结果是&#xff08;&#xff09;_表示空格 #include <stdio.h> int main(void) {printf("%s , %5.3s\n", "computer", "computer");return 0; }A computer , puter B computer , __com C compute…

磁共振成像(MRI)连接组学的应用

前言 如何将磁共振成像(MRI)连接组学应用于研究典型的大脑结构和功能&#xff0c;并在临床环境中用于诊断、预后或治疗&#xff1f;本文将讨论MRI连接组学在评估功能和结构连接方面的可能应用。简而言之&#xff0c;功能连接是一种测量功能磁共振(fMRI)衍生的血氧水平依赖(BOL…

好兄弟离职了,一周面试了20多场,我直呼内行

好兄弟离职之后&#xff0c;一周面试了20多场&#xff0c;最后进了阿里&#xff0c;分享一些面试经历&#xff0c;希望能对大家有帮助&#xff01; 我的面试感受 先说一个字 是真的 “ 累 ” 安排的太满的后果可能就是经常一天只吃一顿饭&#xff0c;一直奔波在路上 不扯这个…

MybatisPlus <= 3.5.3.1 TenantPlugin 组件 存在 sql 注入漏洞(CVE-2023-25330)

漏洞描述 MyBatis-Plus TenantPlugin 是 MyBatis-Plus 的一个为多租户场景而设计的插件&#xff0c;可以在 SQL 中自动添加租户 ID 来实现数据隔离功能。 MyBatis-Plus TenantPlugin 3.5.3.1及之前版本由于 TenantHandler#getTenantId 方法在构造 SQL 表达式时默认情况下未对…

关键词数据分析-搜索词和关键词分析工具

要搜索热门关键词获取&#xff0c;可以采用以下几种方法&#xff1a; 使用百度指数&#xff1a;百度指数是一个实用的工具&#xff0c;可用于查看关键词的热度趋势、搜索量等数据。在百度指数中&#xff0c;您可以输入您要搜索的关键词&#xff0c;并查看近期的相关数据。这可以…