在这篇文章中,我们将学习如何在C++中处理二维(2D)地图,我们用C++代码实例来解释这个概念。
目录
- 简介 - 什么是二维地图?
- 应用
- 入门 - 声明一个二维地图
- 添加和更新键/值
- 访问值
- 擦除键/值对
- 使用初始化器列表初始化一个2D地图
- 遍历2D地图
- 复杂性
简介 - 什么是二维地图?
从本质上讲,二维地图是一个地图的地图,也就是一个嵌套地图。它类似于一个二维数组,是一个数组的数组。
应用

该表显示了二维地图如何存储数据。当有嵌套信息时,二维地图是非常有用的。例如,在上表中,每个人都有一个标识符 "姓名",并有几条嵌套信息(身高、体重和年龄)。
入门 - 声明一个二维地图
创建二维地图的语法与创建一维地图的语法非常相似。
下面是创建一维地图的语法,键是int类型,值是string类型。
一维地图
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, string> map1d;
}
二维地图
下面是创建二维地图的语法。这个地图中的键是ints,值是map。这些内部地图的键是字符串类型,值是int类型。
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
}
添加和更新键/值
添加键和更新值的语法与一维数组的语法非常相似,但是,我们要指定两个键而不是一个。
下面是向map2D添加一个新键(0)的代码,并将其内部地图的键 "key "设置为5。
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
}
以下是工作原理:
由于map2d 是一个2D地图,map2d[0] 本身就是一个地图,键是一个字符串,值是一个int。最初,map2d[0] 没有任何元素,但现在我们给map2d[0] 添加了一个元素,其键为 "key",值为5。现在,map2d有一个元素,其中键是0,值是map。
我们也可以向内部地图添加其他值:
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
map2d[0]["new key"] = 10;
map2d[1]["key"] = 15;
}
我们还可以更新值:
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
map2d[0]["key"] = 10; // Updates the value that was previously set
}
访问值
我们可以使用与添加/更新值相同的语法来访问2D地图中的值。
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
map2d[0]["key"] = 10;
cout << map2d[0]["key"];
}
输出:
10
擦除键/值对
擦除整个内部地图
擦除整个内部地图是相当直接的--我们需要做的就是调用erase 函数,并将我们想要擦除的键作为参数传入。
下面是一个例子:
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
map2d.erase(0); // There is no longer any value for the key 0.
}
作为执行的结果,整个内部地图(也就是map2d 中键0的值)被擦除。
擦除内部地图中的一个特定的键/值
为了擦除内层地图中的特定键/值(例如:map2d[0] 中的 "key"),我们首先需要访问内层地图,然后调用erase 函数。
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
map2d[0].erase("key"); // access map2d at key 0,
// then delete the key "key" from this inner map
}
使用初始化器列表初始化二维地图
当我们创建一个一维地图时,我们可以使用以下格式初始化一个地图。
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, string> map1d = {
{0, "hello"},
{1, "bye"}
};
}
我们可以用类似的方式来初始化一个二维地图。然而,我们不是用一个字符串,而是用一个地图作为值。每一个内层地图的格式都与前面代码段中的地图相同:
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d = {
{0, {{"key", 5}, {"other", 10}}},
{1, {{"key", 15}, {"other", 20}}}
};
上面的代码等同于写:
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
map2d[0]["other"] = 10;
map2d[1]["key"] = 15;
map2d[1]["other"] = 20;
}
遍历一个二维地图
为了迭代一个二维地图,我们需要迭代外层地图和每个内层地图。因此,我们将使用嵌套的for循环。
#include <iostream>
#include <map>
using namespace std;
int main () {
map<int, map<string, int>> map2d;
map2d[0]["key"] = 5;
map2d[0]["other"] = 10;
map2d[1]["key"] = 15;
map2d[1]["other"] = 20;
for (auto outer = map2d.begin(); outer != map2d.end(); outer++) {
// print the key
cout << outer->first << "\n";
//iterate through the value, which is a map
auto inner_map = outer->second;
for (auto inner_iterator = inner_map.begin(); inner_iterator != inner_map.end(); inner_iterator++) {
cout << inner_iterator->first << ": "; //print the inner key
cout << inner_iterator->second << " "; // print the inner value
}
cout << "\n";
}
}
输出:
0
key: 5 other: 10
1
key: 15 other: 20
以下是其工作原理:
为了循环浏览地图,我们使用迭代器。每个地图迭代器都有名为first 和second 的成员,我们使用箭头运算符(->)来访问这些成员。first 是用来访问键的,second 是用来访问地图中每个元素的值。
在外循环中,我们使用了一个叫做outer的迭代器。首先,我们使用cout << outer->first ,打印每个元素的键。然后,我们通过创建一个名为inner_map (为简单起见,指定为auto )的新变量并给它赋值outer->second ,来访问内部地图。
然后,我们创建一个内循环来遍历inner_map ,用一个叫做inner_iterator 的迭代器。在这个循环中,我们使用inner_iterator->first 和inner_iterator->second 打印每个键和值。
复杂性
地图操作
地图操作(例如查找、更新)的时间复杂度是O(log(N))。
迭代
由于我们对每个内层地图进行迭代,完整迭代的总体时间复杂度是O(NM),其中N是外层地图的大小,M是内层地图的大小。
结语
这篇文章到此结束!希望你喜欢阅读。