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
提示:也可以使用迭代器遍历映射,这将在下一章中详细介绍。