在C++中处理二维地图的方法

495 阅读4分钟

在这篇文章中,我们将学习如何在C++中处理二维(2D)地图,我们用C++代码实例来解释这个概念。

目录

  • 简介 - 什么是二维地图?
  • 应用
  • 入门 - 声明一个二维地图
  • 添加和更新键/值
  • 访问值
  • 擦除键/值对
  • 使用初始化器列表初始化一个2D地图
  • 遍历2D地图
  • 复杂性

简介 - 什么是二维地图?

从本质上讲,二维地图是一个地图的地图,也就是一个嵌套地图。它类似于一个二维数组,是一个数组的数组。

应用

2DMap

该表显示了二维地图如何存储数据。当有嵌套信息时,二维地图是非常有用的。例如,在上表中,每个人都有一个标识符 "姓名",并有几条嵌套信息(身高、体重和年龄)。

入门 - 声明一个二维地图

创建二维地图的语法与创建一维地图的语法非常相似。

下面是创建一维地图的语法,键是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 

以下是其工作原理:

为了循环浏览地图,我们使用迭代器。每个地图迭代器都有名为firstsecond 的成员,我们使用箭头运算符(->)来访问这些成员。first 是用来访问键的,second 是用来访问地图中每个元素的值。

在外循环中,我们使用了一个叫做outer的迭代器。首先,我们使用cout << outer->first ,打印每个元素的键。然后,我们通过创建一个名为inner_map (为简单起见,指定为auto )的新变量并给它赋值outer->second ,来访问内部地图。

然后,我们创建一个内循环来遍历inner_map ,用一个叫做inner_iterator 的迭代器。在这个循环中,我们使用inner_iterator->firstinner_iterator->second 打印每个键和值。

复杂性

地图操作

地图操作(例如查找、更新)的时间复杂度是O(log(N))

迭代

由于我们对每个内层地图进行迭代,完整迭代的总体时间复杂度是O(NM),其中N是外层地图的大小,M是内层地图的大小。

结语

这篇文章到此结束!希望你喜欢阅读。