C++ STL - map 与 multimap用法和区别

目录

一、概述

二、用法

2.1、插入

2.2、拷贝与赋值

2.3、查找

2.4、删除

2.5、完整代码

三、其他成员类型


一、概述

map 与 multimap是存储key-value(键-值 对)类型的容器。不同之处在于:map只允许key与 value一一对应;multimap一个key可对应多个value;说白了map规定key值具有唯一性,而multimap不是。

上述使其不同之处,下面如果,不作特别说明,适用于map的都适用于multimap(见代码)

二、用法

2.1、插入

插入可以判断是否插入成功,完整代码见最后一节。下面代码中isInsertOK用于接受返回值,变量类型为:pair< map<vector<int>, int>::iterator, bool>;如果是新手还是像下面这样写一次;熟练以后,直接使用auto isInsertOK代替。

//声明,定义
std::map<int, std::string> m;
m[3] = "h1";
m[0] = "what";
// 构建 key-value
m.insert(std::pair<int, std::string>(2, "love you"));

2.2、拷贝与赋值

允许使用一个map初始化另一个map,如下代码,可以使用vecA初始化vecB。map也重载了等号,直接赋值。

map<vector<int>, int> vecB(vecA); //拷贝构造
map<vector<int>, int> vecC;
vecC = vecA;
vecC.swap(vecA);

2.3、查找

map中,用于查找功能的成员函数有很多,如下:

  • lower_bound("china");   //指向vecD中第一个 = 键值 “china”对应的元素
  • upper_bound("china");   //指向vecD中第一个 > 键值 “china”对应的元素
  • equal_range("china");    //指向vecD中第一个 >= 键值 “china”对应的元素
  • count("china");  //查找key = “china”键值对的个数
  • find("china");  //查找key = “china”对应键值对
 map<string, int> vecD;
// 你以为按照下面初始化 vecD,他的size会是5? 由于insert方法不能覆盖,所以我们将map 改成 multimap
vecD.insert(pair<string, int>((string)"china", 1));
vecD.insert(pair<string, int>((string)"china", 2));//拒绝插入
vecD.insert(pair<string, int>((string)"china", 3));//拒绝插入
vecD.insert(pair<string, int>((string)"english", 1));
vecD.insert(pair<string, int>((string)"english", 2));//拒绝插入

multimap<string, int> vecE;
vecE.insert(make_pair((string)"china", 1));
vecE.insert(make_pair((string)"china", 1));//允许插入
vecE.insert(make_pair((string)"china", 3));//允许插入
vecE.insert(make_pair((string)"china", 4));//允许插入
vecE.insert(make_pair((string)"china", 5));//允许插入
vecE.insert(make_pair((string)"english", 1));
vecE.insert(make_pair((string)"english", 2));//允许插入
vecE.insert(make_pair((string)"america", 1));
vecE.insert(make_pair((string)"america", 2));//允许插入
vecE.insert(make_pair((string)"america", 3));//允许插入
cout << "multimap 初始化" << endl;
cout << "vecE所有元素"<<endl;
printfB(vecE);
//查找区间
multimap<string, int> ::iterator it1 = vecE.lower_bound("china");   //指向vecD中第一个等于键值 “china”对应的元素
multimap<string, int> ::iterator it2 = vecE.upper_bound("china");   //指向vecD中第一个大于键值 “china”对应的元素
cout << it1->first << " " << it1->second << endl;
cout << it2->first << " " << it2->second << endl;
// 等于 = lower_bound + upper_bound
pair<multimap<string, int>::iterator, multimap<string, int>::iterator > it3    = vecE.equal_range("china");
map<string, int>::iterator it4 = it3.first;
map<string, int>::iterator it5 = it3.second;

//查找key = “china”键值对的个数
int iCount = vecE.count("china");

//查找key = “china”对应键值对
multimap<string, int>::iterator it6 = vecE.find("china");

2.4、删除

可以删除multimap中key = "english"的 所有元素指定,直接调用erase函数。也可以删除指定地址范围内的元素,例如:vecE.erase(itBegin_, itEnd_);

multimap<string, int>::iterator itBegin = vecE.begin();
// 删除 vecE 前面三个元素 与 后面 三个元素
// 在改善特征点匹配算法中有实践
int index = 0;
int vecA_size = vecE.size();
//删除(自定义删除任何元素)
for (multimap<string, int>::iterator it_ = vecE.begin(); it_ != vecE.end(); )
{
	//<1>法1
	//vecE.erase(it_++);
	//<2>法2
	if ((0<=index)&&(index<=2))
	{
		it_ = vecE.erase(it_);//这样写,防止指针失效
	}

	else if (((vecA_size - 3) <= index) && (index <= (vecA_size - 1)))
	{
		it_ = vecE.erase(it_);
	}
	else
	{
		it_++;
	}
	++index;
}


//删除multimap中key = "english"的 所有 元素
vecE.erase("english");
cout << "vecE删除key = english的 所有 元素 " << endl;
printfB(vecE);

//删除所有元素
multimap<string, int>::iterator itBegin_ = vecE.begin();
multimap<string, int>::iterator itEnd_ = vecE.end();
vecE.erase(itBegin_, itEnd_);
//bool isEmpty = vecE.empty();

if (vecE.empty())
{
	cout << "vecE已经被清空" << endl;
}

2.5、完整代码

#include<opencv2/opencv.hpp>
#include<map>
#include<iostream>
#include <algorithm>    // std::sort


using namespace std;

//打印函数可写成模板

//打印函数 printfA
void printfA(map<vector<int>, int> vec_)
{
    for (std::map<std::vector<int>, int>::iterator it = vec_.begin(); it != vec_.end(); it++)
    {
        std::cout << it->first[0] << "  " << it->first[1] << "  " << it->first[2] << "  " << it->second << std::endl;
    }
    cout << "容积 = " << vec_.size() << endl;
}

//打印函数 printfB
void printfB(multimap<string, int> vec_)
{
    for (multimap<string, int>::iterator it = vec_.begin(); it != vec_.end(); it++)
    {
        std::cout << it->first  << "  " << it->second << std::endl;
    }
    cout << "容积 = " << vec_.size() << endl;
}

int main()
{
    //声明,定义
    std::map<int, std::string> m;
    m[3] = "h1";
    m[0] = "what";
    // 构建 key-value
    m.insert(std::pair<int, std::string>(2, "love you"));

    std::cout << m[0].c_str() << std::endl;//这里数字 不是索引值了
    std::cout << m[3].c_str() << std::endl;
    std::cout << m[4].c_str() << std::endl;
    std::cout << m[2].c_str() << std::endl;   // 会产生一个新的元素,即m[2] = ""

    m[6] = string("slam2345");
    std::cout << m.size() << std::endl;       // 5
    //遍历
    for (std::map<int, std::string>::iterator it = m.begin(); it != m.end(); it++)
        std::cout << it->first << ", " << it->second.c_str() << std::endl;


    std::vector<int> pointTemp;
    std::map<std::vector<int>, int> vecA;
    for (int y = 0; y < 4; y++)
    {
        for (int x = 0; x < 4; x++)
        {
            pointTemp.push_back(y);
            pointTemp.push_back(x);
            pointTemp.push_back(x + y);
            //插入
            vecA.insert(std::pair<std::vector<int>, int>(pointTemp, (y * 4 + x + 1)));
            pointTemp.clear();
        }
    }
    printfA(vecA);
//***************************************************************************************************
//【注意】区分map与multimap:1、两者都会自动排序 2、multimap插入不会覆盖已有键值对(对于map若有相同key,则拒绝插入)
//<1>插入返回值 判定是否插入成功
    //带插入数据
    vector<int> pointTemp_ = { 1,2,3 }; // Insert方法不能覆盖,如果键已经存在,则插入失败【注意插入位置,是自动排序】
    int a1 = 4;
    //判定插入是否成功
    pair< map<vector<int>, int>::iterator, bool> isInsertOK;//注意这里声明
    isInsertOK = vecA.insert(pair<vector<int>, int>(pointTemp_, a1));
    cout << "插入成功? " << isInsertOK.second << endl;
    //打印
    printfA(vecA);

//***************************************************************************************************
//<2>map对象的拷贝构造与赋值
	map<vector<int>, int> vecB(vecA); //拷贝构造
	map<vector<int>, int> vecC;
	vecC = vecA;
	vecC.swap(vecA);
//***************************************************************************************************
//<3>查找
     map<string, int> vecD;
    // 你以为按照下面初始化 vecD,他的size会是5? 由于insert方法不能覆盖,所以我们将map 改成 multimap
    vecD.insert(pair<string, int>((string)"china", 1));
    vecD.insert(pair<string, int>((string)"china", 2));//拒绝插入
    vecD.insert(pair<string, int>((string)"china", 3));//拒绝插入
    vecD.insert(pair<string, int>((string)"english", 1));
    vecD.insert(pair<string, int>((string)"english", 2));//拒绝插入

    multimap<string, int> vecE;
    vecE.insert(make_pair((string)"china", 1));
    vecE.insert(make_pair((string)"china", 1));//允许插入
    vecE.insert(make_pair((string)"china", 3));//允许插入
    vecE.insert(make_pair((string)"china", 4));//允许插入
    vecE.insert(make_pair((string)"china", 5));//允许插入
    vecE.insert(make_pair((string)"english", 1));
    vecE.insert(make_pair((string)"english", 2));//允许插入
    vecE.insert(make_pair((string)"america", 1));
    vecE.insert(make_pair((string)"america", 2));//允许插入
    vecE.insert(make_pair((string)"america", 3));//允许插入
    cout << "multimap 初始化" << endl;
    cout << "vecE所有元素"<<endl;
    printfB(vecE);
    //查找区间
    multimap<string, int> ::iterator it1 = vecE.lower_bound("china");   //指向vecD中第一个等于键值 “china”对应的元素
    multimap<string, int> ::iterator it2 = vecE.upper_bound("china");   //指向vecD中第一个大于键值 “china”对应的元素
    cout << it1->first << " " << it1->second << endl;
    cout << it2->first << " " << it2->second << endl;
    // 等于 = lower_bound + upper_bound
    pair<multimap<string, int>::iterator, multimap<string, int>::iterator > it3    = vecE.equal_range("china");
    map<string, int>::iterator it4 = it3.first;
    map<string, int>::iterator it5 = it3.second;

    //查找key = “china”键值对的个数
    int iCount = vecE.count("china");

    //查找key = “china”对应键值对
    multimap<string, int>::iterator it6 = vecE.find("china");

//***************************************************************************************************
// <4>删除
    multimap<string, int>::iterator itBegin = vecE.begin();
    // 删除 vecE 前面三个元素 与 后面 三个元素
    // 在改善特征点匹配算法中有实践
    int index = 0;
    int vecA_size = vecE.size();
    //删除(自定义删除任何元素)
    for (multimap<string, int>::iterator it_ = vecE.begin(); it_ != vecE.end(); )
    {
        //<1>法1
        //vecE.erase(it_++);
        //<2>法2
        if ((0<=index)&&(index<=2))
        {
            it_ = vecE.erase(it_);//这样写,防止指针失效
        }

        else if (((vecA_size - 3) <= index) && (index <= (vecA_size - 1)))
        {
            it_ = vecE.erase(it_);
        }
        else
        {
            it_++;
        }
        ++index;
    }


    //删除multimap中key = "english"的 所有 元素
    vecE.erase("english");
    cout << "vecE删除key = english的 所有 元素 " << endl;
    printfB(vecE);

    //删除所有元素
    multimap<string, int>::iterator itBegin_ = vecE.begin();
    multimap<string, int>::iterator itEnd_ = vecE.end();
    vecE.erase(itBegin_, itEnd_);
    //bool isEmpty = vecE.empty();

    if (vecE.empty())
    {
        cout << "vecE已经被清空" << endl;
    }
    return 0;
}

三、其他成员类型

member typedefinitionnotes
key_typeThe first template parameter (Key)
mapped_typeThe second template parameter (T)
value_typepair<const key_type,mapped_type>
key_compareThe third template parameter (Compare)defaults to: less<key_type>
value_compareNested function class to compare elementssee value_comp
allocator_typeThe fourth template parameter (Alloc)defaults to: allocator<value_type>
referencevalue_type&
const_referenceconst value_type&
pointerallocator_traits<allocator_type>::pointerfor the default allocator: value_type*
const_pointerallocator_traits<allocator_type>::const_pointerfor the default allocator: const value_type*
iteratora bidirectional iterator to value_typeconvertible to const_iterator
const_iteratora bidirectional iterator to const value_type
reverse_iteratorreverse_iterator<iterator>
const_reverse_iteratorreverse_iterator<const_iterator>
difference_typea signed integral type, identical to:
iterator_traits<iterator>::difference_type
usually the same as ptrdiff_t
size_typean unsigned integral type that can represent any non-negative value of difference_typeusually the same as size_t

参考:https://cplusplus.com/reference/map/map/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

asp.net core mvc之路由

一、默认路由 &#xff08;Startup.cs文件&#xff09; routes.MapRoute(name: "default",template: "{controllerHome}/{actionIndex}/{id?}" ); 默认访问可以匹配到 https://localhost:44302/home/index/1 https://localhost:44302/home/index https:…

PTL货位指引标签为仓储管理打开新思路

PTL货位指引标签是一种新型的仓储管理技术&#xff0c;它通过LED灯光指引和数字显示&#xff0c;为仓库管理带来了全新的管理思路和效率提升&#xff0c;成为现代物流仓库管理中的重要工具。 首先&#xff0c;PTL货位指引标签为仓储管理业务带来了管理新思路。传统的仓库管理中…

OFDM深入学习及MATLAB仿真

文章目录 前言一、OFDM 基本原理及概念1、OFDM 简介2、子载波3、符号4、子载波间隔与符号长度之间的关系 二、涉及的技术1、保护间隔2、交织3、信道编码4、扩频5、导频6、RF&#xff08;射频&#xff09;调制7、信道估计 三、变量间的关系四、IEEE 802.11a WLAN PHY 层标准五、…

matlab中的mapminmax函数初步理解和应用

matlab中的mapminmax函数初步认识 一、mapminmax 顾名思义&#xff1a;映射最大最小 二、语法及举例 2.1 语法1 [Y,PS] mapminmax(X) 将矩阵X映射形成矩阵Y, Y中每行中的最小值对应-1&#xff0c;最大值对应1。PS是一个包含映射信息的结构体。 举例&#xff1a; clc cle…

Jupyter Notebook 闪退

造成这个的原因非常非常多&#xff01; 比如什么环境变量没有配置&#xff0c;或者说jupyter和python版本不兼容&#xff0c;库不兼容等等。 但是我呢&#xff0c;以上都不是。 我是因为手残&#xff0c;删掉了不该删的文件&#xff1a; 这个操作就是打开"Anaconda Prom…

在react中组件间过渡动画如何实现?

一、是什么 在日常开发中&#xff0c;页面切换时的转场动画是比较基础的一个场景 当一个组件在显示与消失过程中存在过渡动画&#xff0c;可以很好的增加用户的体验 在react中实现过渡动画效果会有很多种选择&#xff0c;如react-transition-group&#xff0c;react-motion&…

Vb6 TCP Server服务端监听多个RFID读卡器客户端上传的刷卡数据

本示例使用设备介绍&#xff1a;WIFI无线4G网络RFID云读卡器远程网络开关物流网阅读器TTS语音-淘宝网 (taobao.com) Option ExplicitConst BUSY As Boolean False 定义常量 Const FREE As Boolean TrueDim ConnectState() As Boolean 定义连接状态 Dim ServerSendbuf(…

Kubernetes实战(四)-部署docker harbor私有仓库

1 Docker原生私有仓库Registry 1.1 原生私有仓库Registry概述 Docker的仓库主要分两类&#xff1a; 私有仓库公有仓库 共有仓库只要在官方注册用户&#xff0c;登录即可使用。但对于仓库的使用&#xff0c;企业还是会有自己的专属镜像&#xff0c;所以私有库的搭建也是很有…

数字化广告运营,小迈科技的关键一步

数据驱动广告运营是小迈科技提升整体经营效率、构建竞争优势的重要选择。 截止目前&#xff0c;小迈科技已经完成了数据驱动的广告运营体系的搭建&#xff0c;并通过与神策数据的深入合作&#xff0c;借力神策客户旅程分析平台&#xff0c;在广告投放、运营活动等各个环节实现了…

网络安全从业者用于学习和了解可以访问的顶级黑客论坛

黑客论坛目前已经成为了网络犯罪者的数字聚集地。在这些论坛上我们可以看见最新的数据泄露事件,软件的漏洞,以及黑客教程。下面我将向大家分享目前还可以访问的顶级黑客论坛,网络安全从业者用于学习和了解。 1.XSS.is(俄罗斯黑客论坛) 推出时间:2013年,2018年9月重新推出…

Jdk 1.8 for mac 详细安装教程(含版本切换)

Jdk 1.8 for mac 详细安装教程&#xff08;含版本切换&#xff09; 官网下载链接 https://www.oracle.com/cn/java/technologies/downloads/#java8-mac 一、选择我们需要安装的jdk版本&#xff0c;这里以jdk8为例&#xff0c;下载 macOS 版本&#xff0c;M芯片下载ARM64版本…

centos7安装docker容器

卸载老版本&#xff1a; $ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine/var/lib/docker/路径下存在镜像、数据卷、容器等&#xff0c;在卸载的时候是不会自动删除…

不同规模的企业如何借助宁盾LDAP统一用户认证实现安全和效率需求?

中小企业要解决安全和业务效率问题&#xff0c;须提前规划软件基础设施&#xff0c;其中最基础的部分是建立统一账号和统一用户身份认证体系。这个体系相当于在软件系统之间建立了一套统一的身份标准&#xff0c;基于这套标准创建的账号让员工方便、高效地访问公司内的大部分软…

【解密ChatGPT】:从过去到未来,揭示其发展与变革

&#x1f38a;专栏【ChatGPT】 &#x1f33a;每日一句&#xff1a;天行健,君子以自强不息,地势坤,君子以厚德载物 ⭐欢迎并且感谢大家指出我的问题 文章目录 一、ChatGPT的发展历程 二、ChatGPT的技术原理 三、ChatGPT的应用场景 四、ChatGPT的未来趋势 五、总结 引言:随着…

基于SSM的高校疫情防控出入信息管理系统(有报告)。Javaee项目。

演示视频&#xff1a; 基于SSM的高校疫情防控出入信息管理系统&#xff08;有报告&#xff09;。Javaee项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Sprin…

三天打鱼两天晒网

文章目录 前言一、题目描述 二、题目分析 三、解题 程序运行代码 前言 本系列为选择结构编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 二、题目分析 三、解题 程序运行代码 #include<stdio.h> int main(){int n;scanf("%d",&n);i…

开发常用的 3种 API 监控报告- Eolink Apikit

API 监控报告是一种监测 API 异常的工具。在 API 管理中&#xff0c;查看 API 异常监控的监控报告&#xff0c;是 Eolink Apikit 常用的功能。Eolink Apikit 的监控报告有3种&#xff1a; 单接口监控报告 流程监控报告 项目监控报告 1、单接口监控报告 单接口监控报告通常关…

jira Licenses更新步骤

有时候我们不想花钱使用jira,那么只有通过一个月以续期的方式来使用jira。下面提供下自己实测的方式 1、获取License Key 登录地址&#xff1a;https://my.atlassian.com 登录自己的Google账号&#xff0c;进入到下面账号&#xff0c;然后点击“New Trial License” product上…

C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发004:游戏核心消息处理 - 玩家类的实现

文章目录 0 代码仓库1 需求2 AOI设计2.1 AOI算法简介2.2 AOI数据结构及实现2.2.1 玩家2.2.2 网格对象2.2.3 游戏世界矩形2.2.4 获取周围玩家的实现2.2.5 代码测试 2.3 GameRole结合AOI创建玩家2.3.1 创建游戏世界全局对象-GameRole继承AOIWorld的Player2.3.2 把玩家到游戏世界的…

聊聊MySQL中的死锁

欢迎关注微信公众号&#xff1a;互联网全栈架构 死锁是指两个或者多个事务互相持有对方所需的资源&#xff0c;从而导致它们都无法继续执行的情况。下图是一个死锁的示例&#xff0c;事务1锁住了id1的数据&#xff08;比如更新id1的数据记录&#xff09;&#xff0c;同时请求锁…