unordered_map 和 unordered_set 的异同

unordered_mapunordered_set 都是 C++ 标准库中的哈希表容器,它们都存储元素并通过哈希函数来优化查找、插入和删除操作。但它们之间有一些重要的区别,下面详细解释:

1. 数据结构类型的不同

  • unordered_map:是一个 关联容器,它存储键值对(key-value pair)。每个元素由键(key)和值(value)组成,键是唯一的,可以通过键快速查找对应的值。
    • 语法:unordered_map<KeyType, ValueType>
  • unordered_set:是一个 集合容器,它只存储键(key),不存储值。集合中的每个元素都是唯一的,且通过哈希值来进行查找。
    • 语法:unordered_set<ElementType>

2. 存储元素的方式

  • unordered_map:存储的是 键值对。每个元素是一个包含键和值的 pair,键值对的形式是 pair<const KeyType, ValueType>。查找时通过键(key)来获取对应的值(value)。
    unordered_map<string, int> map;
    map["apple"] = 5;  // 键 "apple",值 5
    map["banana"] = 3; // 键 "banana",值 3
    
  • unordered_set:存储的是 单独的键,不包含值。每个元素仅由一个键组成,集合中的元素是唯一的。
    unordered_set<string> set;
    set.insert("apple");  // 元素 "apple"
    set.insert("banana"); // 元素 "banana"
    

3. 用途不同

  • unordered_map:当你需要存储一组关联的键值对,并且想通过键快速查找对应的值时,使用 unordered_map
  • unordered_set:当你只关心元素是否存在,而不关心元素的具体值时,使用 unordered_set。例如,你可以用它来存储不重复的元素,并进行集合操作(如求交集、并集等)。

4. 查找与访问

  • unordered_map:通过 查找 。可以使用 map[key] 访问或修改值,也可以使用 find() 来查找键是否存在。
    unordered_map<string, int> map;
    map["apple"] = 5;
    cout << map["apple"]; // 输出 5
    
    // 查找元素
    auto it = map.find("banana");
    if (it != map.end()) {
        cout << it->second;  // 输出对应的值
    }
    
  • unordered_set:通过 查找 是否存在。可以使用 find()count() 来检查某个元素是否在集合中。
    unordered_set<string> set;
    set.insert("apple");
    
    // 查找元素
    if (set.find("apple") != set.end()) {
        cout << "Found apple!";
    }
    

5. 常用操作

  • unordered_map
    • insert(): 插入一个键值对。
    • find(): 查找键并返回对应的迭代器。
    • operator[]: 通过键访问或修改对应的值。
    • erase(): 删除指定键的元素。
  • unordered_set
    • insert(): 插入一个元素。
    • find(): 查找元素并返回对应的迭代器。
    • count(): 检查元素是否存在。
    • erase(): 删除指定元素。

6. 存储和访问时间复杂度

  • unordered_mapunordered_set 都基于哈希表实现,因此它们的 插入、删除、查找 的平均时间复杂度都是 O(1)。不过,在最坏情况下(哈希冲突非常严重时),这些操作的时间复杂度可能退化到 O(n)

7. 内存使用

  • unordered_map:每个元素包含一个键和一个值,因此它的内存开销会比 unordered_set 大。
  • unordered_set:只存储键,因此内存开销比 unordered_map 小。

8. 迭代顺序

  • unordered_mapunordered_set 都不保证元素的顺序。它们内部使用哈希表存储元素,哈希表并不维护插入顺序或任何特定的顺序。因此,遍历 unordered_mapunordered_set 时,元素的顺序是不可预测的。

9. 使用场景举例

  • unordered_map
    • 用于存储频率计数:例如,统计每个单词在文本中出现的次数。
    • 用于存储配置项:例如,查找配置信息。
  • unordered_set
    • 用于去重:例如,查找一个数组中的唯一元素。
    • 用于集合运算:例如,检查两个集合的交集。

示例代码:

unordered_map 示例:

#include <iostream>
#include <unordered_map>
using namespace std;

int main() {
    unordered_map<string, int> map;
    map["apple"] = 5;
    map["banana"] = 3;
    map["cherry"] = 7;

    // 查找
    if (map.find("banana") != map.end()) {
        cout << "Found banana, count: " << map["banana"] << endl;
    }

    // 修改
    map["banana"] = 10;

    // 遍历
    for (const auto& entry : map) {
        cout << entry.first << ": " << entry.second << endl;
    }
    return 0;
}

unordered_set 示例:

#include <iostream>
#include <unordered_set>
using namespace std;

int main() {
    unordered_set<string> set;
    set.insert("apple");
    set.insert("banana");
    set.insert("cherry");

    // 查找
    if (set.find("banana") != set.end()) {
        cout << "Found banana!" << endl;
    }

    // 删除
    set.erase("banana");

    // 遍历
    for (const auto& elem : set) {
        cout << elem << endl;
    }
    return 0;
}

总结:

  • unordered_map:存储 键值对,通过 查找 ,适用于需要通过键访问值的场景。
  • unordered_set:存储 单个键,适用于需要存储不重复的元素,并检查其是否存在的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值