C++之hash映射与集合

​​​​​​C++刷题基础知识(栈、队列、hash、STL、基础函数等)---持续更新-CSDN博客

1.1 unordered_map

1.1.1 unordered_map的基本特性

C++中的 unordered_map 是一种关联容器,它包含了键值对,并且是无序的。每一个键都是唯一的,与对应的值相关联。unordered_map 在内部使用了哈希表来实现,因此它的插入、删除和查找操作的时间复杂度通常是 O(1)。然而,由于哈希冲突的存在,最坏的情况可能会达到 O(n)。

注意:unordered_map 不保证元素的排序,无论是按照键还是值。

1.1.2 unordered_map的代码使用例程

cpp 复制代码
#include <iostream>  
#include <unordered_map>  
#include <string>  
  
int main() {  
    std::unordered_map<std::string, int> my_map;  
      
    // 插入键值对  
    my_map["apple"] = 1;  
    my_map["banana"] = 2;  
    my_map["cherry"] = 3;  
      
    // 查找值  
    int value = my_map["apple"]; // value 现在是1  
    std::cout << "The value of apple is: " << value << std::endl;  
      
    // 检查键是否存在  
    if (my_map.find("orange") == my_map.end()) {  
        std::cout << "The map does not contain orange" << std::endl;  
    }  
      
    // 删除键值对  
    my_map.erase("banana");  
      
    // 遍历键值对  (其中first表示键,而second表示值)
    for (const auto& pair : my_map) {  
        std::cout << pair.first << ": " << pair.second << std::endl;  
    }  
      
    return 0;  
}

1.1.3 unordered_map的用法总结(表格)

函数名 描述
insert() 插入一个或多个键值对
erase() 删除一个或多个键值对
find() 查找指定键的值,如果找不到则返回尾迭代器
count() 返回指定键值的数量
empty() 检查容器是否为空
size() 返回容器中键值对的数量
clear() 删除容器中的所有键值对
swap() 与另一个容器交换内容
begin() 返回指向第一个键值对的迭代器
end() 返回指向尾部的迭代器
cbegin() 返回指向第一个键值对的常量迭代器
cend() 返回指向尾部的常量迭代器
hash_function() 返回用于哈希的函数对象
key_eq() 返回用于比较键的函数对象

1.1.4 map与unordered_map的对比

  1. 实现方式:map基于红黑树实现,保持元素有序,插入和查找的时间复杂度是O(log n)。unordered_map基于哈希表实现,不保持元素有序,插入和查找的时间复杂度平均为O(1),但最坏情况下可能会达到O(n)。
  2. 元素顺序:map中的元素按照键的自然顺序(或者通过自定义比较函数)进行排序,所以遍历得到的元素是有序的。unordered_map中的元素没有特定的顺序,遍历得到的元素顺序与插入顺序无关。
  3. 查找效率:map适用于需要有序数据以及频繁查找的场景。unordered_map适用于对插入和查找性能要求较高,对元素顺序无特别要求的场景。
  4. 内存开销:由于map使用红黑树来维护有序性,它的内存开销通常比unordered_map要高。unordered_map使用哈希表,其内存开销通常较低,但在存储大量数据时,由于哈希表冲突可能需要更多内存。
  5. 需要的关键字类型:map要求关键字类型有比较函数或支持<运算符来进行元素排序。unordered_map要求关键字类型支持哈希函数和==运算符。
  6. C++标准要求:map和unordered_map都是C++标准库的一部分,但在C++11之前,只有map是标准库的部分,而unordered_map是在C++11引入的新容器。
  7. 迭代器稳定性:map的迭代器在插入和删除元素时不会失效,因为它使用红黑树来保持顺序。unordered_map的迭代器在插入元素时可能会失效,因为哈希表的重新哈希过程可能导致元素位置改变。

1.2 set

1.2.1 set的基本特性

C++中的set是一种基于红黑树实现的关联容器,它包含了唯一键值的集合。每个键在set中只能出现一次,不能重复。set的元素按照键的升序排列。

1.2.2 set的代码使用例程

cpp 复制代码
#include <iostream>  
#include <set>  
#include <string>  
  
int main() {  
    std::set<std::string> my_set;  
      
    // 插入元素  
    my_set.insert("apple");  
    my_set.insert("banana");  
    my_set.insert("cherry");  
      
    // 查找元素  
    auto it = my_set.find("banana");  
    if (it != my_set.end()) {  
        std::cout << "Found banana" << std::endl;  
    } else {  
        std::cout << "Banana not found" << std::endl;  
    }  
      
    // 删除元素  
    my_set.erase("banana");  
      
    // 遍历元素  
    for (const auto& item : my_set) {  
        std::cout << item << std::endl;  
    }  
      
    return 0;  
}

1.2.3 set的用法总结(表格)

函数名 描述
insert() 在集合中插入一个或多个元素
erase() 删除集合中的一个或多个元素
find() 在集合中查找指定的元素,如果找到返回一个指向它的迭代器,否则返回尾迭代器
count() 返回集合中等于给定值的元素数量
empty() 检查集合是否为空
size() 返回集合中元素的数量
clear() 删除集合中的所有元素
begin() 返回指向第一个元素的迭代器
end() 返回指向尾部的迭代器
rbegin() 返回指向最后一个元素的反向迭代器
rend() 返回指向尾部的反向迭代器

1.3 unordered_set

1.3.1 unordered_set的基本特性

C++的unordered_set是一种基于哈希表实现的关联容器,它包含了唯一键值的集合。每个键在unordered_set中只能出现一次,不能重复。unordered_set的元素按照键的哈希值进行存储,因此它没有特定的顺序。与有序集合(set)不同,unordered_set不保证元素的排序。

1.3.2 unordered_set的代码使用例程

cpp 复制代码
#include <iostream>  
#include <unordered_set>  
#include <string>  
  
int main() {  
    // 创建一个unordered_set对象  
    std::unordered_set<std::string> my_set;  
      
    // 插入元素  
    my_set.insert("apple");  
    my_set.insert("banana");  
    my_set.insert("cherry");  
      
    // 查找元素  
    auto it = my_set.find("banana");  
    if (it != my_set.end()) {  
        std::cout << "Found banana" << std::endl;  
    } else {  
        std::cout << "Banana not found" << std::endl;  
    }  
      
    // 删除元素  
    my_set.erase("banana");  
      
    // 遍历元素  
    for (const auto& item : my_set) {  
        std::cout << item << std::endl;  
    }  
      
    return 0;  
}

1.3.3 unordered_set的用法总结(表格)

函数名 描述
insert() 在集合中插入一个或多个元素
erase() 删除集合中的一个或多个元素
find() 在集合中查找指定的元素,如果找到返回一个指向它的迭代器,否则返回尾迭代器
count() 返回集合中等于给定值的元素数量
empty() 检查集合是否为空
size() 返回集合中元素的数量
clear() 删除集合中的所有元素
swap() 与另一个集合交换内容
begin() 返回指向第一个元素的迭代器
end() 返回指向尾部的迭代器
cbegin() 返回指向第一个元素的常量迭代器
cend() 返回指向尾部的常量迭代器
hash_function() 返回用于哈希的函数对象
key_eq() 返回用于比较键的函数对象

1.4 pair

1.4.1 pair的基本特性

C++的std::pair是一个用于存储两个不同类型对象的容器,这两个对象可以是不同的类型,而且这两个对象在pair中并不是关联的,也就是说它们的类型并没有直接关系。这两个元素分别称为first和second,pair的所有构造函数都保持first和second的值不变。

1.4.2 pair的代码使用例程

cpp 复制代码
#include <iostream>  
#include <utility> // pair在这个头文件中定义  
  
int main() {  
    // 创建一个pair对象  
    std::pair<int, std::string> p1(42, "Hello");  
      
    // 使用first和second成员函数  
    std::cout << "First element: " << p1.first << std::endl;  
    std::cout << "Second element: " << p1.second << std::endl;  
      
    // 使用赋值操作符  
    std::pair<int, std::string> p2;  
    p2 = p1; // 将p1的值赋给p2  
    std::cout << "p2 first element: " << p2.first << std::endl;  
    std::cout << "p2 second element: " << p2.second << std::endl;  
      
    // 使用swap函数交换两个pair的值  
    std::swap(p1, p2);  
    std::cout << "After swap: " << "p1 first element: " << p1.first << ", p1 second element: " << p1.second << std::endl;  
    std::cout << "After swap: " << "p2 first element: " << p2.first << ", p2 second element: " << p2.second << std::endl;  
      
    return 0;  
}

1.4.3 pair的用法总结(表格)

函数名 描述
first 返回存储在pair中的第一个元素的引用
second 返回存储在pair中的第二个元素的引用
operator= 对pair的赋值操作符
swap() 交换两个pair对象的值

1.5 使用场景及对比

|------|---------------|-----|---------------|
| pair | unordered_map | set | unordered_set |
| key:value模式,区别是一个元素或者多个元素 || value单一元素,区别为是否有序 ||
| | | | |

相关推荐
可均可可21 分钟前
C++之OpenCV入门到提高005:005 图像操作
c++·图像处理·opencv·图像操作
zyx没烦恼25 分钟前
【STL】set,multiset,map,multimap的介绍以及使用
开发语言·c++
机器视觉知识推荐、就业指导37 分钟前
基于Qt/C++与OpenCV库 实现基于海康相机的图像采集和显示系统(工程源码可联系博主索要)
c++·qt·opencv
笨小古1 小时前
路径规划——RRT-Connect算法
算法·路径规划·导航
<但凡.1 小时前
编程之路,从0开始:知识补充篇
c语言·数据结构·算法
f狐0狸x1 小时前
【数据结构副本篇】顺序表 链表OJ
c语言·数据结构·算法·链表
myloveasuka1 小时前
类与对象(1)
开发语言·c++
paopaokaka_luck2 小时前
基于Spring Boot+Vue的多媒体素材管理系统的设计与实现
java·数据库·vue.js·spring boot·后端·算法
视觉小萌新2 小时前
VScode+opencv——关于opencv多张图片拼接成一张图片的算法
vscode·opencv·算法
2的n次方_2 小时前
二维费用背包问题
java·算法·动态规划