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

news2024/11/23 15:22:13

目录

一、概述

二、用法

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/

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

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

相关文章

在医疗影像领域,生成式模型可以做些什么?用什么平台快速实现?使用MONAI框架进行生成式模型开发

生成模型具有巨大的潜力&#xff0c;不仅有助于通过合成数据集安全地共享医疗数据&#xff0c;还可以执行一系列逆向应用&#xff0c;如异常检测、图像到图像翻译、去噪和MRI重建。然而&#xff0c;由于这些模型的复杂性&#xff0c;它们的实现和再现性可能很困难。 对于我这种…

图像分割项目中损失函数的选择

文章目录 前言场景&#xff1a;实际项目中&#xff0c;通常会有一个常见的问题&#xff1a;样本不均衡一、focal loss思考 二、Dice loss三、二分类未完待续 前言 在图像分割领域&#xff0c;最基础、最常见的损失当然是交叉熵损失 —— Cross entropy。随着不断的研究&#x…

一个java文件的JVM之旅

准备 我是小C同学编写得一个java文件&#xff0c;如何实现我的功能呢&#xff1f;需要去JVM(Java Virtual Machine)这个地方旅行。 变身 我高高兴兴的来到JVM&#xff0c;想要开始JVM之旅&#xff0c;它确说&#xff1a;“现在的我还不能进去&#xff0c;需要做一次转换&#x…

OceanBase 如何通过日志观测冻结转储流程?

本文旨在通过日志解析 OceanBase 的冻结转储流程&#xff0c;以其冻结检查线程为切入点&#xff0c;以租户&#xff08;1002&#xff09;的线程名为例。 作者&#xff1a;陈慧明&#xff0c;爱可生测试工程师&#xff0c;主要参与 DMP 和 DBLE 自动化测试项目。 爱可生开源社区…

2258. 逃离火灾 : 详解如何从「二分」到「分类讨论」(图解过程)

题目描述 这是 LeetCode 上的 「2258. 逃离火灾」 &#xff0c;难度为 「困难」。 Tag : 「多源 BFS」、「二分」、「预处理」 给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid&#xff0c;它表示一个网格图。 每个格子为下面 个值之一&#xff1a; 0 表示草地。 1 表…

【狂神说Java】SpringSecurity+shiro

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;【狂神说Java】 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c…

ShuffleNet系列 网络结构

文章目录 ShuffleNet V1Channel Shuffle&#xff1a;通道打散SuffleNet UnitModel Architecture实验结果 ShuffleNet V2Guideline 1Guideline 2Guideline 3Guideline 4模型结构代码 论文&#xff1a;ShuffleNet: ShuffleNet: An Extremely Efficient Convolutional Neural Netw…

2023年的低代码:数字化、人工智能、趋势及未来展望

本文由葡萄城技术团队发布。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 正如许多专家预测的那样&#xff0c;低代码平台在2023年将展现更加强劲的势头。越来越多的企业正在纷纷转向低代…

ArcGIS 气象风场等示例 数据制作、服务发布及前端加载

1. 原始数据为多维数据 以nc数据为例。 首先在pro中需要以多维数据的方式去添加多维数据&#xff0c;这里的数据包含uv方向&#xff1a; 加载进pro的效果&#xff1a; 这里注意 数据属性需要为矢量uv&#xff1a; 如果要发布为服务&#xff0c;需要导出存储为tif格式&…

spring 中 @Validated/@Valid

超级好的链接 添加链接描述

Vue实现面经基础版案例(路由+组件缓存)

一、面经基础版-案例效果分析 1.面经效果演示 2.功能分析 通过演示效果发现&#xff0c;主要的功能页面有两个&#xff0c;一个是列表页&#xff0c;一个是详情页&#xff0c;并且在列表页点击时可以跳转到详情页底部导航可以来回切换&#xff0c;并且切换时&#xff0c;只有…

AI:69-基于深度学习的音乐推荐

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

JavaScript脚本操作CSS

脚本化CSS就是使用JavaScript脚本操作CSS&#xff0c;配合HTML5、Ajax、jQuery等技术&#xff0c;可以设计出细腻、逼真的页面特效和交互行为&#xff0c;提升用户体验&#xff0c;如网页对象的显示/隐藏、定位、变形、运动等动态样式。 1、CSS脚本化基础 CSS样式有两种形式&…

OpenCV 在ImShow窗体上选择感兴趣的区域

窗体上选择感兴趣ROI区域 在计算机视觉处理中, 通常是针对图像中的一个特定区域进行处理, 有时候这个特定区域需要人来选择, OpenCV 也提供了窗口选择ROI机制. 窗体支持两种选择ROI区域的方法, 一个是单选, 一个是多选, 操作方法如下: 单选: 通过鼠标在屏幕上选择区域, 然后通过…

【Linux系统编程十六】:(基础IO3)--用户级缓冲区

【Linux系统编程十六】&#xff1a;基础IO3--用户级缓冲区 一.用户级缓冲区二.缓冲区刷新策略1.验证&#xff1a; 三.缓冲区意义 一.用户级缓冲区 我们首先理解上面的代码&#xff0c;分别使用printf和fprintf&#xff0c;fwrite往1号文件描述符里输出&#xff0c;也就是往显示…

论文阅读——InternImage(cvpr2023)

arxiv&#xff1a;https://arxiv.org/abs/2211.05778 github&#xff1a;https://github.com/OpenGVLab/InternImage 一、介绍 大部分大模型都是基于transformer的&#xff0c;本文是一个基于CNN的视觉基础模型。使用可变性卷积deformable convolution作为核心操作&…

docker复制镜像文件

一、复制镜像 #1. 查找本机已有的镜像docker images |grep xxxx#2. 将镜像复制出来指向到xxxx.tar的文件中 docker save 343cca04e31d > xxxx.tareg: 二、加载镜像 直接将拷贝好的镜像包直接加载即可 docker load < myimage.tar

【C++】一文简练总结【多态】及其底层原理&具体应用(21)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.多态的概念二.多态的实现1&#xff…

Codeforces Round 908 (Div. 2)视频详解

Educational Codeforces Round 157 &#xff08;A--D&#xff09;视频详解 视频链接A题代码B题代码C题代码D题代码 视频链接 Codeforces Round 908 (Div. 2)视频详解 A题代码 #include<bits/stdc.h> #define endl \n #define deb(x) cout << #x << "…