C++一分钟之-map与set容器详解

本文涉及的产品
大数据开发治理平台 DataWorks,不限时长
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,5000CU*H 3个月
简介: 【6月更文挑战第21天】C++ STL的`map`和`set`是基于红黑树的关联容器,提供有序存储和高效查找。`map`存储键值对,键唯一,值可重复;`set`仅存储唯一键。两者操作时间复杂度为O(log n)。常见问题包括键的唯一性和迭代器稳定性。自定义比较函数可用于定制排序规则,内存管理需注意适时释放。理解和善用这些工具能提升代码效率。

在C++ Standard Template Library(STL)中,mapset作为关联容器,为开发者提供了键值对存储和唯一键集合管理的强大工具。它们底层通常基于红黑树实现,保证了元素的有序性和对数时间复杂度的查找效率。本文将深入浅出地解析mapset的使用方法、常见问题及其规避策略,并通过代码示例加以说明。
image.png

1. map:键值对的天堂

map容器存储键值对,其中键是唯一的,值可以重复。键用于排序和查找,值则存储实际数据。map中的元素默认按照键的升序排列。

常见问题与避免策略:

  • 键的唯一性:尝试插入已存在的键会导致插入失败,而不是覆盖原有值。若需覆盖,请先检查键是否存在,再决定插入或更新。
std::map<std::string, int> myMap;
myMap["apple"] = 4; // 插入或更新
if (myMap.find("banana") != myMap.end()) {
   
   
    myMap.erase("banana"); // 删除后再插入实现覆盖效果
    myMap["banana"] = 2;
}
  • 性能考量:查找、插入和删除操作的时间复杂度均为O(log n),但频繁的插入和删除可能导致树的不平衡,影响性能。适度的重平衡(如通过迭代器失效后的自动调整)可以缓解这一问题。

2. set:无重复的键集合

set类似于map,但只存储键,没有对应的值,所有元素都是唯一的。它同样按照键的升序排列。

常见问题与避免策略:

  • 元素唯一性:试图插入重复元素将被忽略,这是set设计的初衷。确保插入前元素的唯一性,或利用此特性进行去重。
std::set<int> mySet;
mySet.insert(1); // 成功插入
mySet.insert(1); // 重复,不会插入
  • 迭代器稳定性:在setmap中,插入新元素或删除现有元素不会导致其他元素的迭代器失效,但插入或删除操作点的迭代器会失效。在遍历时谨慎操作集合。

3. 共同注意事项

  • 自定义比较函数:默认情况下,键按字典顺序排序。可以通过提供自定义比较函数或比较对象来自定义排序规则。
struct CaseInsensitiveCompare {
   
   
    bool operator()(const std::string& lhs, const std::string& rhs) const {
   
   
        return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(),
            [](char a, char b){
   
    return tolower(a) < tolower(b); });
    }
};
std::map<std::string, int, CaseInsensitiveCompare> caseInsensitiveMap;
  • 内存管理mapset中的元素是按需分配的,删除元素不会立即释放内存,直到容器销毁或调用shrink_to_fit()。对于内存敏感的应用,需要注意适时释放不再使用的内存。

总结

mapset作为C++ STL中的重要成员,以其独特的键值存储和集合管理能力,在数据处理和算法实现中扮演着关键角色。正确理解和运用它们,可以显著提升代码的效率和清晰度。面对它们的潜在陷阱,如键的唯一性、性能考量以及迭代器的使用,采取合理的规避策略至关重要。通过实践和不断探索,你将能更加得心应手地驾驭这些强大的容器。

目录
相关文章
|
1天前
|
C++ 容器
C++ STL标准库 《map容器详解》
C++ STL标准库 《map容器详解》
7 0
|
1天前
|
存储 C++ 容器
C++ STL标准库 《map容器详解》
C++ STL标准库 《map容器详解》
7 0
|
1天前
|
C++
【c++】map和set的封装
【c++】map和set的封装
5 0
|
2天前
|
安全 编译器 C++
【C++】学习笔记——类和对象_5
【C++】学习笔记——类和对象_5
17 9
|
2天前
|
编译器 C++
【C++】学习笔记——类和对象_4
【C++】学习笔记——类和对象_4
13 6
|
2天前
|
存储 编译器 C++
【C++】学习笔记——类和对象_3
【C++】学习笔记——类和对象_3
15 6
|
2天前
|
存储 编译器 C语言
【C++】学习笔记——类和对象_2
【C++】学习笔记——类和对象_2
14 3
|
2天前
|
编译器 C语言 C++
【C++】学习笔记——类和对象_1
【C++】学习笔记——类和对象_1
11 3
|
2天前
|
存储 编译器 C语言
【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(上)
【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(上)
7 2
|
1天前
|
C++
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
2 0
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)