c++,map容器的基本操作
C++ 中 std::map 是一个非常有用的关联容器,它提供了一种键值对(key-value)的存储方式,并且会根据键(key)自动进行排序。
1. 头文件与声明
首先,你需要包含 <map> 头文件。
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
// 声明一个 map,key 为 string 类型,value 为 int 类型
map<string, int> myMap;
// 其他操作...
return 0;
}
2. 插入元素 (Insert)
有几种常见的方法可以向 map 中插入元素:
方法一:使用 insert() 函数和 make_pair
myMap.insert(make_pair("Apple", 10));
方法二:使用 insert() 函数和花括号 {} (C++11及以上)
myMap.insert({"Banana", 20});
方法三:使用 emplace() 函数 (C++11及以上,更高效)emplace 会直接在容器内部构造元素,避免了临时对象的创建和拷贝。
myMap.emplace("Orange", 30);
方法四:使用 [] 操作符 (最常用、最直观)
如果键不存在,[] 操作符会先创建一个带有该键的新元素,并将其值初始化为默认值(对于 int 是 0),然后返回这个值的引用让你来赋值。
myMap["Mango"] = 40; // 直接像数组一样赋值
重要区别:
-
insert/emplace:如果键已存在,不会覆盖原有的值,插入操作会失败。 -
[]操作符:如果键已存在,会覆盖原有的值。
3. 访问元素 (Access)
方法一:使用 [] 操作符
cout << "Apple: " << myMap["Apple"] << endl; // 输出 10
注意:如果键 "Apple" 不存在,myMap["Apple"] 会自动创建一个键为 "Apple",值为 0 的元素。这有时不是你想要的行为。
方法二:使用 at() 函数 (更安全)
cout << "Banana: " << myMap.at("Banana") << endl; // 输出 20
注意:如果键 "Banana" 不存在,at() 会抛出一个 std::out_of_range 异常。
方法三:使用迭代器 (Iterator) 遍历访问
// 使用迭代器遍历 map (按键的升序排列)
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
// it->first 是 key, it->second 是 value
cout << it->first << ": " << it->second << endl;
}
// C++11 起支持的更简洁的范围基于 for 循环
for (const auto &pair : myMap) {
cout << pair.first << ": " << pair.second << endl;
}
4. 查找元素 (Find)
使用 find() 函数来检查一个键是否存在。这是最推荐的方法,因为它不会意外创建新元素。
// 查找键 "Cherry"
auto it = myMap.find("Cherry");
// 判断是否找到
if (it != myMap.end()) {
cout << "Found Cherry: " << it->second << endl;
} else {
cout << "Cherry not found." << endl;
}
find() 返回一个指向该元素的迭代器,如果没找到,则返回 myMap.end()。
5. 删除元素 (Erase)
方法一:通过迭代器删除
// 先找到要删除的元素
auto it = myMap.find("Apple");
if (it != myMap.end()) {
myMap.erase(it); // 通过迭代器删除
}
方法二:通过键直接删除
// 直接通过键删除,返回删除的元素个数 (对于 map,只能是 0 或 1)
size_t numErased = myMap.erase("Banana");
cout << "Erased " << numErased << " elements." << endl;
方法三:删除一个范围内的元素 (不常用)
// 删除从 begin() 开始的两个元素 myMap.erase(myMap.begin(), next(myMap.begin(), 2));
6. 其他常用操作
检查是否为空
if (myMap.empty()) {
cout << "Map is empty." << endl;
}
获取元素个数
cout << "Map size: " << myMap.size() << endl;
清空 map
myMap.clear();
综合示例
下面是一个将所有操作整合在一起的完整示例:
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
// 1. 声明 & 插入
map<string, int> fruitBasket;
fruitBasket.insert({"Apple", 5});
fruitBasket.emplace("Banana", 3);
fruitBasket["Orange"] = 8;
fruitBasket["Mango"] = 6; // 使用 [] 插入
// 尝试插入一个已存在的键 (不会生效)
fruitBasket.insert({"Apple", 100}); // Apple 的值仍然是 5
// 2. 访问 & 遍历
cout << "Fruit basket contents:" << endl;
for (const auto &pair : fruitBasket) {
cout << " " << pair.first << ": " << pair.second << endl;
}
// 3. 查找
string searchKey = "Mango";
auto it = fruitBasket.find(searchKey);
if (it != fruitBasket.end()) {
cout << "\nFound " << searchKey << ", quantity: " << it->second << endl;
} else {
cout << "\n" << searchKey << " not found." << endl;
}
// 4. 修改 (通过 find 检查后使用 [] 修改)
fruitBasket["Apple"] = 10; // 修改 Apple 的数量
cout << "\nApple quantity updated to: " << fruitBasket["Apple"] << endl;
// 5. 删除
fruitBasket.erase("Banana");
cout << "\nAfter erasing Banana, size: " << fruitBasket.size() << endl;
// 6. 安全访问示范
try {
cout << "Trying to access a non-existing key with at()..." << endl;
cout << fruitBasket.at("DragonFruit") << endl;
} catch (const out_of_range &e) {
cout << "Error: " << e.what() << " (Key not found)" << endl;
}
// 使用 find 安全访问
it = fruitBasket.find("DragonFruit");
if (it != fruitBasket.end()) {
cout << "DragonFruit: " << it->second << endl;
} else {
cout << "Safely determined DragonFruit is not in the basket." << endl;
}
return 0;
}
关键特点总结:
-
有序性:
std::map中的元素总是按照键(key)的升序进行排序。 -
唯一性:每个键只能在 map 中出现一次。
-
底层实现:通常基于红黑树(一种平衡二叉搜索树)实现,因此插入、删除、查找操作的时间复杂度均为 O(log n)。
-
替代品:如果你不需要排序,但需要更快的访问速度(平均 O(1)),可以考虑
std::unordered_map(基于哈希表)。
deepseek辅助创作
更多推荐


所有评论(0)