C++ 映射
C++ 映射
映射 (Map) 以"键/值"对的形式存储元素。
映射中的元素:
- 通过键(而非索引)访问,每个键都是唯一的
- 自动按键的升序排序
要使用映射,需要包含 <map> 头文件:
// 包含映射库 #include <map>
创建映射
使用 map 关键字创建映射,在尖括号 <> 中指定键和值的类型,然后指定映射名称,格式为:
map<keytype, valuetype> mapName
实例
// 创建一个名为 people 的映射,键为字符串,值为整数 map<string, int> people
如果要在声明时添加元素,可以将元素放在花括号 {} 内的逗号分隔列表中:
实例
// 创建存储人名和年龄的映射
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
访问映射元素
不能像数组和向量那样通过索引号访问映射元素,而是通过方括号 [] 内的键来访问:
实例
// 创建存储人名和年龄的映射
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 获取键 "Bill" 对应的值
cout << "Bill is: " << people["Bill"] << "\n";
// 获取键 "Steve" 对应的值
cout << "Steve is: " << people["Steve"] << "\n";
也可以使用 .at() 函数访问元素:
实例
// 创建存储人名和年龄的映射
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 获取键 "Steve" 对应的值
cout << "Steve is: " << people.at("Steve") << "\n";
// 获取键 "Elon" 对应的值
cout << "Elon is: " << people.at("Elon") << "\n";
注意:.at() 函数通常比方括号 [] 更受青睐,因为如果元素不存在它会抛出错误信息:
实例
// 创建存储人名和年龄的映射
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 尝试访问不存在的元素(将抛出异常)
cout << people.at("Jack");
修改值
可以修改与键关联的值:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 将 Bill 的值从 19 改为 50
people["Bill"] = 50;
cout << "Bill is: " << people["Bill"]; // 现在输出 Bill is: 50
不过使用 .at() 函数更安全:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 将 Bill 的值从 19 改为 50
people.at("Bill") = 50;
cout << "Bill is: " << people.at("Bill"); // 现在输出 Bill is: 50
添加元素
可以使用方括号 [] 向映射添加元素:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 添加新元素
people["Jack"] = 23;
people["John"] = 25;
people["Percy"] = 18;
people["Alfred"] = 36;
也可以使用 .insert() 函数:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 添加新元素
people.insert({"Jack", 23});
people.insert({"John", 25});
people.insert({"Percy", 18});
people.insert({"Alfred", 36});
相同键的元素
映射不能有相同键的元素。
例如,如果我们尝试向映射添加两次 "Jack",它只会保留第一个:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 尝试添加两个键相同的元素
people.insert({"Jack", 23});
people.insert({"Jack", 30});
总结:值可以相同,但键必须唯一。
移除元素
要从映射中移除特定元素,可以使用 .erase() 函数:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 通过键移除元素
people.erase("Bill");
要移除映射中的所有元素,可以使用 .clear() 函数:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
// 移除所有元素
people.clear();
获取映射大小
要获取映射中元素的数量,可以使用 .size() 函数:
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
cout << people.size(); // 输出 3
检查映射是否为空
使用 .empty() 函数检查映射是否为空。
如果映射为空,.empty() 函数返回 1(true),否则返回 0(false):
实例
map<string, int> people; cout << people.empty(); // 输出 1(映射为空)
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
cout << people.empty(); // 输出 0(不为空)
注意:也可以通过 .count(key) 函数检查特定元素是否存在。
如果元素存在返回 1(true),否则返回 0(false):
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
cout << people.count("Bill"); // 输出 1(Bill 存在)
遍历映射
可以使用 for-each 循环遍历映射。但需要注意几点:
- 应在循环中使用
auto关键字(C++11 引入),让编译器自动确定每个键值对的正确数据类型 - 由于映射元素包含键和值,在循环中需要使用
.first访问键,.second访问值 - 映射中的元素按键的升序自动排序
实例
map<string, int> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
for (auto person : people) {
cout << person.first << " is: " << person.second << "\n";
}
输出结果将是:
Bill is: 19 Elon is: 26 Steve is: 32
如果要反转排序顺序,可以在尖括号中使用 greater<type> 函数对象:
实例
map<string, int, greater<string>> people = { {"Bill", 19}, {"Steve", 32}, {"Elon", 26} };
for (auto person : people) {
cout << person.first << " is: " << person.second << "\n";
}
输出结果将是:
Steve is: 32 Elon is: 26 Bill is: 19
提示:也可以使用迭代器遍历映射,这将在下一章中详细介绍。