在 C++ 中使用 STL 无序映射容器

Jinku Hu 2023年1月30日 2021年6月28日
  1. 使用 std::unordered_map 元素在 C++ 中声明一个无序映射容器
  2. 使用 contains 成员函数检查 C++ 映射中是否存在给定元素
  3. 使用 erase 成员函数从 C++ 中的映射中删除特定元素
  4. 使用 insert 成员函数在 C++ 中向映射添加新元素
在 C++ 中使用 STL 无序映射容器

本文解释了如何在 C++ 中使用 STL unordered_map 容器的几种方法。

使用 std::unordered_map 元素在 C++ 中声明一个无序映射容器

std::unordered_map 元素实现了一个键值对的关联容器,其中每个键都是唯一的。与 std::map 不同,std::unordered_map 容器不按排序顺序存储元素。因此,容器主要用于元素查找,位置无关紧要。此外,不能保证对象生命周期内元素的位置是固定的。因此,程序员应该将顺序视为未定义。

以下示例演示了 unordered_map 容器的列表初始化,然后输出两个映射的内容。请注意,m1 元素的降序并不意味着它们已排序。

#include <iostream>
#include <unordered_map>
#include <map>

using std::cout; using std::endl;
using std::string;

template<typename Map>
void printMap(Map& m) {
    for (auto& p: m)
        cout << p.first << " : " << p.second << ";" << endl;
    cout << endl;
}

int main()
{
    std::unordered_map<int, string> m1 = { {1, "apple"},
                                    {2, "banana"},
                                    {3, "grape"},
                                    {4, "orange"}, };

    std::map<int, string> m2 = { {1, "apple"},
                                           {2, "banana"},
                                           {3, "grape"},
                                           {4, "orange"}, };

    printMap(m1);
    printMap(m2);

    return EXIT_SUCCESS;
}

输出:

4 : orange;
3 : grape;
2 : banana;
1 : apple;

1 : apple;
2 : banana;
3 : grape;
4 : orange;

使用 contains 成员函数检查 C++ 映射中是否存在给定元素

自 C++20 更新以来,contains 成员函数已成为 std::unordered_map 容器的一部分。你可以使用该函数检查 Map 中是否存在给定元素。此命令接受键值作为唯一参数,如果找到键,则返回 true。该函数具有恒定的平均运行时间,最坏的情况是线性的,取决于容器本身的大小。

#include <iostream>
#include <unordered_map>
#include <map>

using std::cout; using std::endl;
using std::string;

template<typename Map>
void printMap(Map& m) {
    for (auto& p: m)
        cout << p.first << " : " << p.second << ";" << endl;
    cout << endl;
}

int main()
{
    std::unordered_map<int, string> m1 = { {1, "apple"},
                                    {2, "banana"},
                                    {3, "grape"},
                                    {4, "orange"}, };


    for (int x: {1, 2, 3, 4, 5}) {
        if (m1.contains(x)) {
            cout << x << ": Found\n";
        } else {
            cout << x << ": Not found\n";
        }
    }

    return EXIT_SUCCESS;
}

输出:

1: Found
2: Found
3: Found
4: Found
5: Not found

使用 erase 成员函数从 C++ 中的映射中删除特定元素

你可以使用 erase 成员函数从 Map 中删除给定的键值对。该函数具有三个重载,第一个将迭代器带到需要从容器中删除的 map 元素。第二个函数重载需要两个迭代器来指定范围,该范围将从 Map 中删除。请注意,给定范围必须是调用容器对象内的有效范围。第三个重载可以获取应该删除的元素的键值。

在下面的示例中,我们删除每个具有偶数作为键值的元素。

#include <iostream>
#include <unordered_map>
#include <map>

using std::cout; using std::endl;
using std::string;

template<typename Map>
void printMap(Map& m) {
    for (auto& p: m)
        cout << p.first << " : " << p.second << ";" << endl;
    cout << endl;
}

int main()
{
    std::unordered_map<int, string> m1 = { {1, "apple"},
                                    {2, "banana"},
                                    {3, "grape"},
                                    {4, "orange"}, };

    for (auto it = m1.begin(); it != m1.end(); ) {
        if (it->first % 2 == 0)
            it = m1.erase(it);
        else
            ++it;
    }
    printMap(m1);

    return EXIT_SUCCESS;
}

输出:

3 : grape;
1 : apple;

使用 insert 成员函数在 C++ 中向映射添加新元素

unordered_map 容器的另一个核心成员函数是 insert 函数,你可以使用它向 Map 添加新元素。该函数有多个重载,但我们使用第一个只接受键值对的重载。请注意,我们还使用 std::make_pair 函数来构造具有给定参数值的新对。

#include <iostream>
#include <unordered_map>
#include <map>
#include <vector>

using std::cout; using std::endl;
using std::string; using std::vector;

template<typename Map>
void printMap(Map& m) {
    for (auto& p: m)
        cout << p.first << " : " << p.second << ";" << endl;
    cout << endl;
}

int main()
{
    std::unordered_map<int, string> m1 = { {1, "apple"},
                                    {2, "banana"},
                                    {3, "grape"},
                                    {4, "orange"}, };

    vector<string> vec {"papaya",
                        "olive",
                        "melon"};

    auto count = 0;
    for (const auto &item : vec) {
        m1.insert(std::make_pair(count, item));
    }
    printMap(m1);

    return EXIT_SUCCESS;
}

输出:

0 : papaya;
4 : orange;
3 : grape;
2 : banana;
1 : apple;
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C++ Map