C++基础之map容器精讲
今天我们来详细讲解一下 C++ 中的 std::map<int, int>
一、map是什么
map<int, int> 是 C++ 标准模板库(STL)中的一个关联容器。你可以把它想象成一个特殊的数组,但这个数组的“下标”(我们称之为 键,Key)不一定是连续的整数,可以是任何类型(在这里我们指定为 int),并且它会根据键的值自动进行排序。
-
第一个
int:表示键(Key)的数据类型。就像数组的索引,用来查找数据。 -
第二个
int:表示值(Value)的数据类型。就是通过键关联到的实际数据。 -
map容器的特点:容器中的元素总是按照键(Key)从小到大自动排序的。
每个元素都是一个 std::pair<const int, int> 对象,它包含两个部分:
-
first: 键(Key),是const类型,意味着一旦插入就不能修改。 -
second: 值(Value),可以修改。
其中每个Key都有一个Value,Value默认为0。Key就好像是一个独一无二的人,是不可变的,而Value是这个人的资产,是可以改变的。
二、map的优势(与普通数组的区别)
假设你有一个普通数组 int arr[10],你只能用 0 到 9 这样的连续整数作为索引。但如果你需要用学生的学号(比如 20240001)作为索引来查找成绩,或者用单词作为索引来查找它的解释,或者用非连续、甚至是非数字的键来查找数据。
这时普通数组就无能为力了,而 std::map 就派上了用场。对于 map<int, int>,虽然键也是 int,但它可以是任意整数,并且顺序是排好的。也可以用map<string, int>,通过字符串来找到该字符串对应的Value,并且顺序也是拍好了的(通过字典序)
三、基本用法
使用map需要包含头文件#include <map>,当然也可以用万能头#include <bits/stdc++.h>
1.创建(声明)一个 map
#include <iostream>
#include <map>
using namespace std;
int main() {
map<int, int> mp; // 创建一个键和值都是int类型的空map
}
2.插入数据
我这里只推荐使用[ ]运算符
mp[8] = 750; // 如果键8不存在,会创建它并赋值750。如果已存在,则会修改它的值。
mp[4]; // 如果键4没有设置Value,那么默认初始为0
3.访问和遍历数据
1.使用[ ]运算符访问
cout << "The value for key 8 is: " << mp[8] << endl; // 输出 750
2.遍历(迭代)map(元素会自动按键排序)
cout << "Iterating through the map:" << endl;
//begin是map的首位,end是map的最后一位的后一位
for (auto it = mp.begin(); it != mp.end(); ++it) {
// it->first 是键, it->second 是值
cout << "Key: " << it->first << ", Value: " << it->second << endl;
}
输出
Key: 1, Value: 200
Key: 2, Value: 50
Key: 3, Value: 100
Key: 4, Value: 300
Key: 5, Value: 600
Key: 8, Value: 750
你会发现输出顺序是 1, 2, 3, 4, 5, 8,而不是你插入的顺序。这就是自动排序的特性。
3.范围 for 循环
for (const auto &pair : mp) // 使用引用避免拷贝
{
cout << "Key: " << pair.first << ", Value: " << pair.second << endl;
}
或者
for (const auto &[x,y] : mp)
{
cout << "Key: " << x << ", Value: " << y << endl;
}
4.查找元素
建议使用 find() 函数,它比直接用 [] 访问更安全,因为它不会创建新元素。
int key_to_find = 5;
auto it = mp.find(key_to_find); // 查找键为5的元素
if (it != mp.end()) {
// 找到了
cout << "Found! Value is: " << it->second << endl;
} else {
cout << "Key " << key_to_find << " not found in the map." << endl;
}
5.删除元素
mp.erase(3); // 删除键为3的元素
//还可以通过迭代器删除
auto it = mp.find(2);
if (it != mp.end()) {
myMap.erase(it);
}
6.检查是否为空和获取大小
if (mp.empty()) {
cout << "The map is empty." << endl;
} else {
cout << "The map has " << mp.size() << " elements." << endl;
}
四、注意事项和常见用途
1.注意事项
-
排序:
std::map基于红黑树实现,元素总是有序的。如果你不需要排序,但需要键值对,可以考虑std::unordered_map(基于哈希表,平均访问速度更快,但元素无序)。 -
[]运算符的副作用:如之前所说,myMap[some_key]如果找不到some_key,会创建一个新元素。如果你只是想检查一个键是否存在,应该使用find()方法。 -
键的唯一性:
std::map中每个键只能出现一次。如果你插入一个已存在的键,新的值会覆盖旧的值(使用insert方法插入已存在的键不会覆盖,插入会失败。但使用[]赋值会覆盖)。如果需要重复的键,可以使用std::multimap。
2.常见用途
计数器(例题-找到最多的数)
vector<int> numbers = {1, 2, 2, 3, 3, 3, 4};
map<int, int> countMap;
for (int num : numbers) {
countMap[num]++; //妙用:如果num不存在,会创建并初始化为0,然后++变为1。
}
//现在 countMap[1]==1, countMap[2]==2, countMap[3]==3, countMap[4]==1
建立映射关系:如学号映射到成绩,产品ID映射到价格等。
更多推荐
所有评论(0)