std::unordered_map 简单使用

本文详细介绍了C++标准库中的unordered_map容器,包括其快速查找、无序特性、动态扩展、哈希冲突处理,以及各种初始化、赋值、查找和操作方法。

目录

std::unordered_map介绍

初始化方式:

1. 直接初始化:

2. 复制初始化:

3. C++11 之后的 emplace 初始化:

赋值方式:

1. 使用 operator[] 进行赋值:

2. 使用 insert 函数:

3. 使用范围初始化:

1. 使用迭代器遍历:

2. 使用范围-based for 循环遍历:

3. 使用 C++11 之后的 auto 关键字:

4. 使用 for_each 算法(需要  头文件):

增加元素:

1. 使用 operator[]:

2. 使用 insert 函数:

3. 使用 emplace 函数(C++11及更高版本):

删除元素:

1. 使用 erase 函数:

修改元素:

直接使用 operator[] 或 insert:

查找元素:

1. 使用 find 函数:

2. 使用范围-based for 循环或迭代器遍历查找:


std::unordered_map介绍


std::unordered_map 是 C++ 标准库中的一种关联容器,用于实现键值对的存储和快速查找。它基于哈希表实现,具有以下特性:

特性:

  1. 快速查找: 由于底层使用哈希表,std::unordered_map 具有快速的查找性能。平均情况下,查找、插入和删除操作的时间复杂度为 O(1)。
  2. 无序性: 与 std::map 不同,std::unordered_map 中的元素是无序的,即它们没有特定的顺序。如果需要有序性,应该使用 std::map
  3. 可变大小: 可以动态添加或删除键值对,而不需要提前指定容器的大小。
  4. 哈希冲突处理: 哈希表中可能会发生哈希冲突,std::unordered_map 采用开链法来处理冲突,即在每个哈希桶中维护一个链表。

优点:

  1. 快速查找: 对于大规模数据集,std::unordered_map 提供了快速的查找操作,使其成为高效的数据结构。
  2. 灵活性: 可以动态地插入和删除元素,适用于动态变化的数据集。
  3. 哈希表的均摊复杂度: 在理想情况下,哈希表的均摊复杂度为 O(1),提供了高效的性能。

缺点:

  1. 空间占用: 由于哈希表需要维护额外的空间来存储哈希桶和链表,可能会占用较多的内存空间。
  2. 不适合有序操作: 如果需要有序迭代或者按照键的顺序访问元素,std::unordered_map 不是最佳选择,应该考虑使用 std::map
  3. 性能不稳定: 在某些情况下,哈希表的性能可能会退化,导致查找、插入和删除操作的时间复杂度升高。

以下是 std::unordered_map 的简单用法示例:

#include <iostream>
#include <unordered_map>

int main() {
    // 创建一个 unordered_map
    std::unordered_map<int, std::string> myMap;

    // 插入键值对
    myMap[1] = "One";
    myMap[2] = "Two";
    myMap[3] = "Three";

    // 查找元素
    auto it = myMap.find(2);
    if (it != myMap.end()) {
        std::cout << "Key 2 found, Value: " << it->second << std::endl;
    } else {
        std::cout << "Key 2 not found." << std::endl;
    }

    // 遍历 unordered_map
    for (const auto& pair : myMap) {
        std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
    }

    return 0;
}

在这个例子中,我们创建了一个 std::unordered_map,插入了一些键值对,并且演示了查找和遍历操作。
std::unordered_map 的初始化和赋值方式有多种,取决于使用的 C++ 版本和个人偏好。以下是一些常见的初始化和赋值方式:

初始化方式:

1. 直接初始化:
#include <unordered_map>

std::unordered_map<int, std::string> myMap1;  // 默认构造函数,创建一个空的 unordered_map

std::unordered_map<int, std::string> myMap2 = {
  
  {1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用初始化列表进行初始
### 使用 `std::unordered_map` 的方法 #### 1. 简介 `std::unordered_map` 是 C++ 标准库中的关联容器之一,基于哈希表实现。它允许以键值对的形式存储数据,并支持高效的插入、删除和查找操作,平均时间复杂度为 \(O(1)\)[^2]。 #### 2. 声明与初始化 `std::unordered_map` 可以通过多种方式声明和初始化。以下是常见的几种形式: - **默认构造** 创建一个空的 `std::unordered_map` 对象。 ```cpp std::unordered_map<std::string, int> myMap; ``` - **列表初始化** 使用初始值列表直接填充容器。 ```cpp std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"cherry", 7}}; ``` #### 3. 插入元素 有多种方法可以向 `std::unordered_map` 中插入键值对: - **使用下标运算符** 如果键不存在,则会创建一个新的键值对并将值设为默认值(对于基本类型通常是零)。 ```cpp myMap["orange"] = 4; // 插入新键值对 "orange": 4 ``` - **使用 `insert` 方法** 这种方法不会覆盖已存在的键。 ```cpp myMap.insert({"grape", 6}); // 插入新键值对 "grape": 6 ``` #### 4. 查找元素 可以通过以下两种常见的方式查找特定键是否存在及其对应的值: - **使用 `find` 方法** 返回指向目标键值对的迭代器;如果没有找到则返回 `end()`。 ```cpp auto it = myMap.find("banana"); if (it != myMap.end()) { std::cout << "Value of banana: " << it->second << std::endl; } ``` - **使用下标运算符** 若键存在,则返回其对应值;否则插入该键并赋予默认值后再返回。 ```cpp int value = myMap["banana"]; // 获取香蕉的数量 ``` #### 5. 删除元素 可以从 `std::unordered_map` 中移除单个键值对或多组连续的键值对: - **使用 `erase` 方法按键名删除** ```cpp myMap.erase("apple"); // 删除苹果的相关记录 ``` - **使用 `clear` 清空整个容器** ```cpp myMap.clear(); // 移除所有键值对 ``` #### 6. 遍历容器 遍历 `std::unordered_map` 中的所有键值对可采用如下方式: - **范围基循环** ```cpp for (const auto& pair : myMap) { std::cout << pair.first << ": " << pair.second << std::endl; } ``` - **传统迭代器** ```cpp for (auto it = myMap.begin(); it != myMap.end(); ++it) { std::cout << it->first << ": " << it->second << std::endl; } ``` #### 7. 特性总结 尽管 `std::unordered_map` 提供了高效的数据存取能力,但也有一些局限性需要注意: - 键值对无固定顺序排列[^4]; - 在极端情况下(如大量哈希碰撞发生时),性能可能下降至线性级别\(O(n)\)[^2]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

telllong

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值