std::map学习
1、声明
#include <map>
#include <string>
int main() {
// 声明一个键为int类型,值为std::string类型的std::map
std::map<int,std::string> myMap;
return 0;
}
2、操作
#include <map>
#include <string>
int main() {
// 声明一个键为int类型,值为std::string类型的std::map
std::map<int,std::string> myMap;
// 一、插入元素
// 1、使用insert
myMap.insert({1, "one"});
myMap.insert(std::make_pair(2, "two"));
// 2、使用emplace(c++11,更高效)
myMap.emplace(3,"three");
// 3、使用[]操作符(如果键不存在会创建)
myMap[4] = "four"; // 4这个键不存在,创建
myMap[1] = "noOne"; // 1这个键存在,覆盖
return 0;
}
3、访问元素
#include <map>
#include <string>
#include <iostream>
int main() {
// 声明一个键为int类型,值为std::string类型的std::map
std::map<int,std::string> myMap;
// 一、插入元素
// 1、使用insert
myMap.insert({1, "one"});
myMap.insert(std::make_pair(2, "two"));
// 2、使用emplace(c++11,更高效)
myMap.emplace(3,"three");
// 3、使用[]操作符(如果键不存在会创建)
myMap[4] = "four"; // 4这个键不存在,创建
myMap[1] = "noOne"; // 1这个键存在,覆盖
// 二、访问元素
// 1、使用 [] 访问(不推荐用于查找,因为不存在时会创建)
std::string value = m[1]; // 如果键不存在,会插入默认值
// 2、使用 at()(C++11,安全访问,不存在时抛出异常)
try {
std::string value = m.at(5);
} catch (const std::out_of_range& e) {
std::cout << "Key not found" << std::endl;
}
// 3、使用 find() 查找(推荐)
auto it = m.find(2);
if (it != m.end()) {
std::cout << "Found: " << it->first << " -> " << it->second << std::endl;
}
return 0;
}
4、删除元素
#include <map>
#include <string>
int main() {
// 声明一个键为int类型,值为std::string类型的std::map
std::map<int,std::string> myMap;
// 一、插入元素
// 1、使用insert
myMap.insert({1, "one"});
myMap.insert(std::make_pair(2, "two"));
// 2、使用emplace(c++11,更高效)
myMap.emplace(3,"three");
// 3、使用[]操作符(如果键不存在会创建)
myMap[4] = "four"; // 4这个键不存在,创建
myMap[1] = "noOne"; // 1这个键存在,覆盖
// 二、删除元素
// 1、根据键删除
m.erase(3);
// 2、根据迭代器删除
auto it = m.find(2);
if (it != m.end()) {
m.erase(it);
}
// 3、删除范围
m.erase(m.begin(), m.find(4));
// 4、清空所有
m.clear();
return 0;
}
5、遍历元素
#include <map>
#include <string>
#include <iostream>
int main() {
std::map<int, std::string> m = {{1, "one"}, {2, "two"}, {3, "three"}};
// 1、C++11 范围for循环(推荐)
for (const auto& pair : m) {
std::cout << pair.first << " -> " << pair.second << std::endl;
}
// 2、C++17 结构化绑定(简洁)
for (const auto& [key, value] : m) {
std::cout << key << " -> " << value << std::endl;
}
// 3、使用迭代器
for (auto it = m.begin(); it != m.end(); ++it) {
std::cout << it->first << " -> " << it->second << std::endl;
}
// 4、反向遍历
for (auto it = m.rbegin(); it != m.rend(); ++it) {
std::cout << it->first << " -> " << it->second << std::endl;
}
return 0;
}
6、常用函数
std::map<int, std::string> m;
// 容量相关
m.empty(); // 是否为空
m.size(); // 元素个数
m.max_size(); // 最大容量
// 查找相关
m.count(1); // 返回键为1的元素个数(map中只能是0或1)
m.contains(1); // C++20,是否包含键
m.lower_bound(2); // 第一个不小于2的迭代器
m.upper_bound(2); // 第一个大于2的迭代器
m.equal_range(2); // 返回pair<lower_bound, upper_bound>
7、自定义排序
// 降序排列
std::map<int, std::string, std::greater<int>> m1;
// 自定义比较函数
struct Compare {
bool operator()(const int& a, const int& b) const {
return a > b;
}
};
std::map<int, std::string, Compare> m2;
// 使用lambda(C++11)
auto cmp = [](int a, int b) { return a > b; };
std::map<int, std::string, decltype(cmp)> m3(cmp);
8、其他
std::map<std::string, int> ages = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 22}
};
// 使用contains检查(C++20),ages的key包不包含Alice
if (ages.contains("Alice")) {
std::cout << "Alice is " << ages["Alice"] << " years old\n";
}
9、常见错误
// ❌ 错误:在循环中删除
for (auto it = m.begin(); it != m.end(); ++it) {
if (it->second == "delete") {
m.erase(it); // it失效
}
}
// ✅ 正确:使用erase返回下一个迭代器
for (auto it = m.begin(); it != m.end(); ) {
if (it->second == "delete") {
it = m.erase(it);
} else {
++it;
}
}
// ❌ 错误:使用[]查找不存在的键
if (m["key"] == value) { // 如果key不存在,会插入默认值!
// ...
}
// ✅ 正确:使用find
if (auto it = m.find("key"); it != m.end() && it->second == value) {
// ...
}