c++ std::map使用笔记
- 1. 包含头文件
- 2. 创建和初始化
- 3. 插入元素
- 4. 访问元素
- 5. 遍历元素
- 6. 查找元素
- 7. 删除元素
- 8. 其他常用操作
- 9. 自定义排序规则
- 10. 示例代码
- 输出结果:
- 总结
std::map
是 C++ 标准库中的一个关联容器,用于存储键值对(key-value pairs)。它基于红黑树实现,因此键是唯一的,并且元素会按照键的顺序自动排序。插入、删除和查找操作的时间复杂度均为 (O(\log n))。
以下是 std::map
的简单使用指南:
1. 包含头文件
首先需要包含 <map>
头文件:
#include <map>
#include <iostream>
2. 创建和初始化
可以创建一个空的 std::map
,或者使用初始化列表进行初始化:
std::map<std::string, int> map1; // 创建一个空的 map
std::map<std::string, int> map2 = {{"Alice", 25},{"Bob", 30},{"Charlie", 35}
}; // 使用初始化列表
3. 插入元素
使用 insert()
方法或 []
运算符插入键值对:
map1.insert({"Alice", 25});
map1.insert(std::make_pair("Bob", 30));// 使用 [] 运算符插入或更新值
map1["Charlie"] = 35;
map1["Alice"] = 26; // 更新 Alice 的值
4. 访问元素
使用 []
运算符或 at()
方法访问元素:
std::cout << "Alice's age: " << map1["Alice"] << std::endl; // 使用 [] 访问
std::cout << "Bob's age: " << map1.at("Bob") << std::endl; // 使用 at() 访问
注意:[]
运算符会在键不存在时自动插入一个默认值,而 at()
会抛出 std::out_of_range
异常。
5. 遍历元素
可以使用范围 for 循环或迭代器来遍历 std::map
:
// 使用范围 for 循环
for (const auto& pair : map2) {std::cout << pair.first << ": " << pair.second << std::endl;
}// 使用迭代器
for (auto it = map1.begin(); it != map1.end(); ++it) {std::cout << it->first << ": " << it->second << std::endl;
}
6. 查找元素
使用 find()
方法查找元素。如果找到,返回指向该键值对的迭代器;否则返回 end()
:
auto it = map2.find("Charlie");
if (it != map2.end()) {std::cout << "Charlie found! Age: " << it->second << std::endl;
} else {std::cout << "Charlie not found!" << std::endl;
}
7. 删除元素
使用 erase()
方法删除元素:
map2.erase("Bob"); // 删除键为 "Bob" 的元素auto it = map1.find("Alice");
if (it != map1.end()) {map1.erase(it); // 通过迭代器删除元素
}
8. 其他常用操作
size()
:返回map
中键值对的数量。empty()
:检查map
是否为空。clear()
:清空map
。count()
:返回某个键的出现次数(对于std::map
,只能是 0 或 1)。lower_bound()
和upper_bound()
:用于范围查找。
if (!map1.empty()) {std::cout << "Map1 size: " << map1.size() << std::endl;
}map1.clear(); // 清空 map// 使用 count 检查键是否存在
if (map2.count("Charlie")) {std::cout << "Charlie exists in map2!" << std::endl;
}// 使用 lower_bound 和 upper_bound
auto low = map2.lower_bound("B"); // 第一个键 >= "B" 的元素
auto high = map2.upper_bound("C"); // 第一个键 > "C" 的元素
std::cout << "Range [B, C]: ";
for (auto it = low; it != high; ++it) {std::cout << it->first << ": " << it->second << " ";
}
std::cout << std::endl;
9. 自定义排序规则
std::map
默认使用 <
运算符对键进行排序。可以通过提供自定义比较函数或函数对象来改变排序规则:
// 使用 greater<string> 实现降序排序
std::map<std::string, int, std::greater<std::string>> map3 = {{"Alice", 25},{"Bob", 30},{"Charlie", 35}
};// 自定义比较函数
struct CaseInsensitiveCompare {bool operator()(const std::string& a, const std::string& b) const {return std::tolower(a[0]) < std::tolower(b[0]);}
};std::map<std::string, int, CaseInsensitiveCompare> map4 = {{"apple", 10},{"Banana", 20},{"cherry", 30}
};for (const auto& pair : map4) {std::cout << pair.first << ": " << pair.second << std::endl;
}
10. 示例代码
以下是一个完整的示例代码:
#include <map>
#include <iostream>
#include <string>int main() {std::map<std::string, int> map = {{"Alice", 25},{"Bob", 30},{"Charlie", 35}};// 插入元素map.insert({"David", 40});map["Eve"] = 45;// 遍历并打印元素std::cout << "Map elements:" << std::endl;for (const auto& pair : map) {std::cout << pair.first << ": " << pair.second << std::endl;}// 查找元素auto it = map.find("Charlie");if (it != map.end()) {std::cout << "Charlie found! Age: " << it->second << std::endl;}// 删除元素map.erase("Bob");map.erase(it);// 再次遍历并打印元素std::cout << "Map after erase:" << std::endl;for (const auto& pair : map) {std::cout << pair.first << ": " << pair.second << std::endl;}// 使用 lower_bound 和 upper_boundauto low = map.lower_bound("C");auto high = map.upper_bound("E");std::cout << "Range [C, E]:" << std::endl;for (auto it = low; it != high; ++it) {std::cout << it->first << ": " << it->second << std::endl;}return 0;
}
输出结果:
Map elements:
Alice: 25
Bob: 30
Charlie: 35
David: 40
Eve: 45
Charlie found! Age: 35
Map after erase:
Alice: 25
David: 40
Eve: 45
Range [C, E]:
David: 40
Eve: 45
总结
std::map
是一个高效的关联容器,适合存储键值对并自动按键排序。它的主要特点包括:
- 键的唯一性。
- 自动按键排序。
- 高效的查找、插入和删除操作((O(\log n)))。
- 支持自定义排序规则。
如果需要存储重复键,可以使用 std::multimap
。