std::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 
#include 

int main() {
    // 创建一个 unordered_map
    std::unordered_map 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 

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

std::unordered_map myMap2 = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用初始化列表进行初始化
2. 复制初始化:
#include 

std::unordered_map anotherMap(myMap2);
// 使用另一个 unordered_map 进行复制初始化
3. C++11 之后的 emplace 初始化:
#include 

std::unordered_map myMap;
myMap.emplace(1, "One");
myMap.emplace(2, "Two");
// 使用 emplace 函数插入键值对

赋值方式:

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

std::unordered_map myMap;
myMap[1] = "One";
myMap[2] = "Two";
// 使用 operator[] 赋值
2. 使用 insert 函数:
#include 

std::unordered_map myMap;
myMap.insert({1, "One"});
myMap.insert(std::make_pair(2, "Two"));
// 使用 insert 函数插入键值对
3. 使用范围初始化:
#include 
#include 

std::unordered_map myMap;
myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用初始化列表进行赋值

这些方式可以根据具体情况选择,初始化和赋值的方式可能会影响代码的可读性和性能。使用初始化列表的方式在 C++11 及更高版本中变得更加流行,因为它更简洁。

std::unordered_map 的遍历方式有多种,以下是一些常见的遍历方式:

1. 使用迭代器遍历:

#include 
#include 

int main() {
    std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};

    // 使用迭代器遍历
    for (auto it = myMap.begin(); it != myMap.end(); ++it) {
        std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
    }

    return 0;
}

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

#include 
#include 

int main() {
    std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};

    // 使用范围-based for 循环遍历
    for (const auto& pair : myMap) {
        std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
    }

    return 0;
}

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

#include 
#include 

int main() {
    std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};

    // 使用 auto 关键字
    for (const auto& entry : myMap) {
        std::cout << "Key: " << entry.first << ", Value: " << entry.second << std::endl;
    }

    return 0;
}

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

#include 
#include 
#include 

void printKeyValue(const std::pair& pair) {
    std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}

int main() {
    std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};

    // 使用 for_each 算法
    std::for_each(myMap.begin(), myMap.end(), printKeyValue);

    return 0;
}

以上这些方式可以根据个人喜好和代码的上下文选择。使用范围-based for 循环和迭代器的方式是比较常见和直观的。

对于 std::unordered_map,增删改查的方式可以通过以下方法实现:

增加元素:

1. 使用 operator[]
#include 

std::unordered_map myMap;
myMap[1] = "One";
myMap[2] = "Two";
2. 使用 insert 函数:
#include 

std::unordered_map myMap;
myMap.insert({1, "One"});
myMap.insert(std::make_pair(2, "Two"));
3. 使用 emplace 函数(C++11及更高版本):
#include 

std::unordered_map myMap;
myMap.emplace(1, "One");
myMap.emplace(2, "Two");

删除元素:

1. 使用 erase 函数:
#include 

std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};

// 删除指定键的元素
myMap.erase(2);

// 删除迭代器指向的元素
auto it = myMap.find(1);
if (it != myMap.end()) {
    myMap.erase(it);
}

// 删除一定范围的元素
myMap.erase(myMap.begin(), myMap.end());

修改元素:

直接使用 operator[] 或 insert
#include 

std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};

// 修改元素
myMap[2] = "NewTwo";

// 或者使用 insert 函数
myMap.insert({3, "NewThree"});

查找元素:

1. 使用 find 函数:
#include 
#include 

std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {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;
}
2. 使用范围-based for 循环或迭代器遍历查找:
#include 
#include 

std::unordered_map myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};

// 使用范围-based for 循环
for (const auto& pair : myMap) {
    if (pair.first == 2) {
        std::cout << "Key 2 found, Value: " << pair.second << std::endl;
        break;
    }
}

// 使用迭代器
auto it = std::find_if(myMap.begin(), myMap.end(),
                       [](const auto& pair) { return pair.first == 2; });

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

上述代码演示了如何使用 std::unordered_map 进行增删改查操作。选择适当的方法取决于具体的需求和代码上下文。

你可能感兴趣的:(C++基础实战,C++新特性,哈希算法,散列表,算法,C++,开发语言)