C++ 二维、三维 map 的使用_c++ 二维map-程序员宅基地

技术标签: C/C++  多维map  map  Stl map  

前言

最近复习了一下 map 的使用,因为使用的都是一维的,所以使用常规操作就能满足需求。以前看到过有人在工作环境中使用多维度的 map,当时没有尝试实现这种需求,今天想起来了就试了下。类似于 map<string, map<string, string>>  这种形式。常规操作是对数据的增删查改

 

二维 map

创建一个二维map,这里以string为例:

map<string, map<string, string>> b;

 

增加元素

增加元素可分为两种情况:(1) 增加若干个数据时可以使用 map 中的 insert() 方法,或者 insert_or_assign() 方法。两者的区别:使用insert()方法时,若相应key不存在,则完成插入操作。反之,则不做插入操作。使用 insert_or_assign() 方法时,若相应 key 不存在,则完成插入操作。反之,完成赋值操作。

(2) 增加单独的数据可以使用赋值方法 test[ "维度1" ][ "维度2" ] = " 字符串 ";,这种方法既简单又方便。若原容器中没有相应的 key ,则完成插入操作,反之完成赋值操作。

for(int i = 0; i < 3; i++)
{
	temp = to_string(i);
	c.insert(make_pair(temp, "string"));
}

//将含有3个元素的 map c 插入到 map b中
b.insert(make_pair(temp, c));

//添加一个元素
b["2"]["1"] = "123456";

 

删除元素

使用 map 中的 erase() 方法删除容器中的一个值或某一维度下的全部值 (删除键为 key 的若干条数据) 。

b["2"].erase("1");
在第一个维度 key 为 "2" 的前提下,删除第二个维度 key 为 "1" 的值。

b.erase("1");
表明删除第一个维度 key 为 "1" 的所有的值。

 

查找与修改

简单的查找可以使用 map 中的 find() 完成,这里主要介绍遍历时的操作。遍历是最常用的查找操作,在遍历过程中,满足一定条件后完成相应的操作。修改操作可以使用赋值语句完成,这里不再赘述。若想对一个二维 map 进行遍历,需要使用两个迭代器,具体请看代码:

void Print(map<string, map<string, string>> a)
{
	map<string, map<string, string>>::iterator p2;
	map<string, string>::iterator p3;

	for(p2 = a.begin(); p2 != a.end(); p2++)
	{
		for(p3 = p2->second.begin(); p3 != p2->second.end(); p3++)
			cout << p2->first << ":" << "[" <<p3->first << "]" << "[" << p3->second << "]" <<endl;
	}
	cout <<endl;
}

修改容器中特定的数据,可以进行遍历,然后对满足条件的元素完成操作,其做法类似于一维 map 的操作:

#include <map>
#include <iostream>
int main()
{
	std::map<int, std::string> c = {
   {1, "one"}, {2, "two"}, {3, "three"},
		{4, "four"}, {5, "five"}, {6, "six"}};

	for(auto it = c.begin(); it != c.end(); )
		if(it->first % 2 == 1)
			//完成相应操作
		else
			++it;
	for(auto& p : c)
		std::cout << p.second << ' ';
}

 

完整代码:

#include <iostream>
#include <map>
#include <string>

using namespace std;

void Print(map<string, map<string, string>> a)
{
	map<string, map<string, string>>::iterator p2;
	map<string, string>::iterator p3;

	for(p2 = a.begin(); p2 != a.end(); p2++)
	{
		for(p3 = p2->second.begin(); p3 != p2->second.end(); p3++)
			cout << p2->first << ":" << "[" <<p3->first << "]" << "[" << p3->second << "]" <<endl;
	}
	cout <<endl;
}

int main()
{
	map<string, map<string, string>> b;
	map<string, string> c;
	string temp;

	//对 map c 进行初始化
	for(int i = 0; i < 3; i++)
	{
		temp = to_string(i);
		c.insert(make_pair(temp, "string"));
	}

	//将 map c 插入到 map b 中
	b.insert(make_pair(temp, c));
	cout << "Init:" <<endl;
	Print(b);

	//修改数据
	b["2"]["1"] = "123456";
	b["2"]["2"] = "qweasd";
	cout << "Modified:" <<endl;
	Print(b);

	b["2"].erase("1");
	cout << "Erase:" <<endl;
	Print(b);

	cout << "Add element:" <<endl;
	b["3"]["3"] = "3333";   
	Print(b);

	return 0;
}

 

三维 map

三维 map 的操作和二维 map 的操作相同,只是多了一个维度,这里仅放一个简单的代码作为参考:

#include <iostream>
#include <map>
#include <string>
#include <vector>

using namespace std;

void Print(map<string, map<string, map<string, string>>> a)
{
	map<string, map<string, map<string, string>>>::iterator p1;
	map<string, map<string, string>>::iterator p2;
	map<string, string>::iterator p3;
	for(p1 = a.begin(); p1 != a.end(); p1++)
	{
		for(p2 = p1->second.begin(); p2 != p1->second.end(); p2++)
		{
			for(p3 = p2->second.begin(); p3 != p2->second.end(); p3++)
				cout << "Row:[ " << p1->first << " ] Column:[ " << p2->first << " ] Timestamp:" << "[ " <<p3->first << " ]" << " ->  [" << p3->second << "]" <<endl;
		}
	}
	cout <<endl;
}

int main()
{
	map<string, map<string, map<string, string>>> a;
	map<string, map<string, string>> b;
	map<string, string> c;
	string temp;
	
	//初始化并插入
	for(int i = 0; i < 2; i++)
	{
		temp = to_string(i);
		c.insert(make_pair(temp, "string"));
		b.insert(make_pair(temp, c));
		a.insert(make_pair(temp, b));
	}
	cout << "Init:" <<endl;
	Print(a);

	//修改
	a["1"]["1"]["0"] = "123456";
	a["1"]["1"]["1"] = "qwerty";
	cout << "Modified:" <<endl;
	Print(a);


	a["1"].erase("1");
	cout << "Erase column == 1:" <<endl;
	Print(a);

	a.erase("1");
	cout << "Erase row == 1:" <<endl;
	Print(a);
	
	return 0;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_38289815/article/details/106022456

智能推荐

docker启动elasticsearch异常Failed to create node environment(解决)-程序员宅基地

文章浏览阅读1.1w次,点赞12次,收藏8次。我自己编写了docker-compose文件用来启动elasticsearch,docker-compose文件如下:version: '2'services: hdback-elasticsearch: #自己生成的elasticsearch集成ik分词器镜像 image: ***/elasticsearch-with-ik:6.4.3 ..._failed to create node environment

Qt 通过ffmpeg获取视频预览图(windows下)_qt获取视频缩略图-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏16次。ffmpeg + qt 实现预览图_qt获取视频缩略图

Flutter 左右菜单联动_flutter左右联动菜单-程序员宅基地

文章浏览阅读1.1w次,点赞8次,收藏23次。效果:像这种左右菜单联动的效果很常见,即点击左边菜单列表右边刷新,这里演示一下在Flutter中的实现页面结构很简单,分为左右结构,左边是一个ListView,右边也是一个ListView,然后按比例显示即可 return new Row( mainAxisAlignment: MainAxisAlignment.start, children: &l..._flutter左右联动菜单

【PCBA方案开发】关于宠物秤的PCBA方案设计_额温枪方案商,提供pcba-程序员宅基地

文章浏览阅读385次。电子秤的种类有很多,包括蓝牙电子秤、厨房秤、宠物秤、珠宝秤、脂肪秤等;这些秤因着在不同的行业应用所以需要的功能也有不同。所以今天PCBA方案设计鼎盛合就来聊下关于宠物秤的PCBA方案设计。宠物秤的PCBA方案主要结构由压力传感器、模拟信号转换器、主控MCU、LED/LCD显示屏及电池这几大类组成。对于宠物秤软件开发的功能实现上主要以单位显示、称重测量、自动去皮及过载提示、自动校准等功能。宠..._额温枪方案商,提供pcba

FOC项目知识点总结三 | 完全搞懂 Clarke 与 Park 变换(附动图,仿真文件以及详细讲解数学推导过程)_clarke park-程序员宅基地

文章浏览阅读1.8w次,点赞75次,收藏382次。本文目的,最终可以完整推算两种变换Clarke 变换首先先看我们需要用到的两种坐标系1. 自然坐标系 abcabcabc我们知道,通过三相逆变电路,我们可以画出一个自然坐标系 abcabcabc ,即三相电压的坐标系,通入的电流在这三轴坐标系中变化:将三个矢量相加合并在一起就如下图所展现:使用三个坐标轴来表示十分的麻烦与不直观,因为其是非正交的,于是乎我们想要将其转化成使用两个正交的坐标轴来表示,于是乎便有了 Clarke变换。Clarke 变换的作用: 将基于三轴二维的定子静止坐标系的各_clarke park

时变系统多传感器信息融合kalman滤波器_卡尔曼滤波器可以使用多种观测方程吗-程序员宅基地

文章浏览阅读3.3k次,点赞9次,收藏50次。前面的博客中讲得都是针对一种传感器的测量值有状态空间模型对系统状态值进行估计,本次博客讨论多传感器下对系统状态值估计的方法,即多传感器的数据融合。多传感器的状态融合又分成两种:1.集中式kalman滤波;2.分布式卡尔曼滤波。集中式kalman滤波是通过将多个观测方程集中为一个观测方程,然后进行标准kalman滤波,该方法可以得到全局的最优估计,但是缺点也是很明显,多个观测方程集中为一个观测方程,..._卡尔曼滤波器可以使用多种观测方程吗

随便推点

【一文讲通】BLDC的六步法&PMSM的FOC法综合_bldc和pmsm电机的驱动电路-程序员宅基地

文章浏览阅读9.1k次,点赞30次,收藏301次。查阅 n^2 的各方资料,对 BLDC&PMSM 进行一个大综合、大整理,查阅、比较和整理 大量的 网络教程、大厂手册、开源解决方案,在这里形成 原理和解决方案 的打通式介绍。_bldc和pmsm电机的驱动电路

腾讯直播——推流SDK(Android)_手机腾讯推流测试工具-程序员宅基地

文章浏览阅读1.4w次。https://www.qcloud.com/document/product/267/4735功能篇腾讯视频云RTMP SDK由两部分构成:推流器 + 播放器,本文将主要介绍推流器的相关信息。该SDK遵循标准RTMP视频推送协议,可以对接包括腾讯云在内的标准视频直播服务器。与此同时,SDK内部囊括了腾讯音视频团队多年的技术积累,在视频压缩、_手机腾讯推流测试工具

阿里云面经之实习hr面_阿里实习 改base-程序员宅基地

文章浏览阅读3.2k次。两天前的晚上接到的hr的电话,直接面试。面试官说了全程30分钟,愣是被我拖到了40分钟。传闻阿里hr不简单,如今一面,果然不简单~从自我介绍开始就初见端倪。面试官上来让我自我介绍前就给了一堆条条框框,要讲你的教育背景,成绩,获得的奖学金,参与学校的项目,产出,参加学校、国家或者国际的比赛情况(建议准备好纸笔记录)。然后hr就抓住其中我讲的一个项目开始了提问模式。首先是介绍项目背..._阿里实习 改base

【数组】- 如何在C++的数组中查找元素?_c++数组查找某个元素-程序员宅基地

文章浏览阅读1.4w次,点赞6次,收藏30次。查找数组元素数组是C++语言重要的数据结构,对它的一些基本操作要熟练掌握。今天,我们就来讨论,如何实现数组元素的查找?案例描述给你m个整数,查找其中有无值为n的数,有则输出该数第一次出现的位置,没有则输出-1。输入第一行一个整数m:数的个数 ( 0 <= m <= 100 ) 第二行m个整数(空格隔开)( 这些数在 0-1000000范围内 ) 第三行为要查找的数n。例如:41 2 3 33输出n的位置或-1。例如:#include <iostream>_c++数组查找某个元素

遗传算法、遗传算法库函数ga和gamultiobj、遗传算法工具箱GOT实例介绍-程序员宅基地

文章浏览阅读7.5k次,点赞24次,收藏187次。分别介绍了常规的遗传算法、使用matlab封装函数库ga和gamultiobj的遗传算法、使用optimtool工具箱的遗传算法,并且给出详细的注释和解析,以及有求最大值和最小值的例子。_gamultiobj

redis为什么是单线程_Redis 为什么用单线程模型?终于知道了!-程序员宅基地

文章浏览阅读81次。Java技术栈www.javastack.cn关注阅读更多优质文章Redis 作为广为人知的内存数据库,在玩具项目和复杂的工业级别项目中都看到它的身影,然而 Redis 却是使用单线程模型进行设计的,这与很多人固有的观念有所冲突,为什么单线程的程序能够抗住每秒几百万的请求量呢?这也是我们今天要讨论的问题之一。除此之外,Redis 4.0 之后的版本却抛弃了单线程模型这一设计,原本使用单线..._redis线程模型为啥是单线程

推荐文章

热门文章

相关标签