✨博客主页 | ||
---|---|---|
何曾参静谧的博客 | ||
📌文章专栏 | ||
「C/C++」C/C++程序设计 | ||
📚全部专栏 | ||
「VS」Visual Studio | 「C/C++」C/C++程序设计 | 「UG/NX」BlockUI集合 |
「Win」Windows程序设计 | 「DSA」数据结构与算法 | 「UG/NX」NX二次开发 |
「QT」QT5程序设计 | 「File」数据文件格式 | 「PK」Parasolid函数说明 |
目录
- std::map容器深度解析
- 1. 引用头文件
- 2. 注意事项
- 3. 函数构造与对象初始化
- 4. 元素访问
- 5. 迭代器
- 6. 容器修改器
- 7. 元素比较
- 总结与应用场景
std::map容器深度解析
1. 引用头文件
在C++标准模板库(STL)中,std::map
是一个重要的关联容器,它提供了基于键(key)的快速查找、插入和删除操作,同时保证元素按键排序。要使用std::map
,首先需要包含其对应的头文件:
#include <map>
2. 注意事项
- 键唯一性:
std::map
中的键是唯一的,不允许重复。 - 自动排序:元素会根据提供的比较函数(默认为
<
运算符)对键进行排序。 - 键值对存储:
std::map
存储的是键值对(key-value pairs),每个键都映射到一个值。 - 不支持随机访问:由于底层实现为红黑树,
std::map
不支持通过下标访问元素。
3. 函数构造与对象初始化
std::map
提供了多种构造函数来初始化对象:
- 默认构造函数:创建一个空的
map
容器。 - 拷贝构造函数:用另一个
map
容器来初始化新的map
容器。 - 赋值构造函数:通过赋值运算符从一个
map
容器创建另一个map
容器。 - 初始化列表构造函数:使用初始化列表来初始化
map
容器。 - 迭代器范围构造函数:使用两个迭代器(指向容器或其他序列的起始和结束位置)来初始化
map
容器。
示例代码:
#include <map>
#include <iostream>
#include <string>int main() {// 默认构造函数std::map<std::string, int> m1;// 初始化列表构造函数std::map<std::string, int> m2 = {{"apple", 1}, {"banana", 2}, {"cherry", 3}};// 拷贝构造函数std::map<std::string, int> m3(m2);// 迭代器范围构造函数(假设有一个数组)// 注意:这里不适用数组,因为map是键值对,所以通常使用其他容器或初始化列表// 但为了演示,我们仍然可以用一个pair数组来初始化std::pair<std::string, int> arr[] = {{"date", 4}, {"elderberry", 5}, {"fig", 6}};std::map<std::string, int> m4(arr, arr + 3);// 输出map元素(自动按键排序)for (const auto& kv : m4) {std::cout << kv.first << ": " << kv.second << std::endl;}return 0;
}
4. 元素访问
std::map
提供了多种方式来访问元素:
- at:通过键访问元素,如果键不存在则抛出
std::out_of_range
异常。 - operator[]:通过键访问元素,如果键不存在则插入一个具有该键的新元素,并返回其值的引用。
- find:查找具有指定键的元素,并返回一个指向该元素的迭代器(如果找到)或
end()
迭代器(如果未找到)。
示例代码:
#include <map>
#include <iostream>
#include <string>int main() {std::map<std::string, int> m = {{"apple", 1}, {"banana", 2}, {"cherry", 3}};// 使用at访问元素try {std::cout << "Banana count: " << m.at("banana") << std::endl;} catch (const std::out_of_range& e) {std::cerr << "Key not found: " << e.what() << std::endl;}// 使用operator[]访问元素(如果键不存在则插入)m["date"] = 4;std::cout << "Date count: " << m["date"] << std::endl;// 使用find查找元素auto it = m.find("cherry");if (it != m.end()) {std::cout << "Cherry count: " << it->second << std::endl;} else {std::cout << "Cherry not found in the map." << std::endl;}return 0;
}
5. 迭代器
std::map
的迭代器是双向迭代器,支持向前和向后遍历容器中的元素。迭代器指向的是键值对(std::pair<const Key, T>
),其中Key
是键的类型,T
是值的类型。由于std::map
的迭代器与底层红黑树结构相关联,因此在插入和删除操作时(除了被删除的迭代器外),其余迭代器仍然有效。
#include <iostream>
#include <map>
#include <string> int main() { std::map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}, {"cherry", 3}}; // 范围for循环(range-based for loop)for (const auto& pair : myMap) { std::cout << pair.first << ": " << pair.second << std::endl; } // 迭代器遍历for (auto it = myMap.begin(); it != myMap.end(); ++it) { std::cout << it->first << ": " << it->second << std::endl; } // 反向迭代器遍历for (auto it = myMap.rbegin(); it != myMap.rend(); ++it) { std::cout << it->first << ": " << it->second << std::endl; } return 0;
}
6. 容器修改器
std::map
提供了多种成员函数来修改容器:
- insert:插入键值对(如果键已存在,则插入失败,除非使用带有提示的插入方法)。
- erase:删除具有指定键的元素。
- clear:清除所有元素。
- swap:交换两个
map
容器的元素。
示例代码:
#include <map>
#include <iostream>
#include <string>int main() {std::map<std::string, int> m = {{"apple", 1}, {"banana", 2}, {"cherry", 3}};// 插入元素auto result = m.insert({"date", 4});if (result.second) {std::cout << "Inserted date successfully." << std::endl;} else {std::cout << "Date already exists in the map." << std::endl;}// 删除元素m.erase("banana");// 清除所有元素// m.clear();// 输出修改后的map元素for (const auto& kv : m) {std::cout << kv.first << ": " << kv.second << std::endl;}return 0;
}
7. 元素比较
std::map
中的元素是根据提供的比较函数(默认为<
运算符)对键进行排序的。因此,可以直接使用比较运算符来比较std::map
中的键或迭代器指向的键值对中的键。
总结与应用场景
std::map
是一个功能强大的关联容器,它提供了基于键的快速查找、插入和删除操作,同时保证元素按键排序。std::map
适用于需要快速根据键查找、插入和删除元素的场景,如:
- 字典或符号表:将字符串映射到整数、浮点数或其他类型的值。
- 缓存:将键映射到缓存的值,以加快数据访问速度。
- 配置管理:将配置选项的名称映射到其值。
- 需要保持元素有序性的场景:如任务调度、资源管理等,其中键的自然顺序或自定义顺序很重要。
通过合理使用std::map
容器,可以显著提高程序的效率和可靠性,特别是在需要处理大量键值对且需要快速查找和插入操作的场景中。