目录
1、insert方式插入、[ ] 方式插入、 emplace方式插入
一、描述
C++ STL (Standard Template Library) 中的 map
是一个关联容器,用于存储键值对(key-value pairs),并且这些键值对是按照键的排序顺序存储的。map
内部通常实现为红黑树(一种自平衡二叉查找树),这使得插入、删除和查找操作的时间复杂度都为 O(log n)。
二、定义和初始化
使用std::map 来访问,如果头部信息包含 using namespace std;则不需要std::,可以直接使用map<xx, yy>, xx 和 yy 是变量,可以是同一类型,也可以不是同一类型;
#include <map>
#include <string>
// 定义一个空的map,键为int类型,值为string类型
std::map<int, std::string> myMap;
// 使用初始化列表来定义并初始化map
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
三、插入元素
1、insert方式插入、[ ] 方式插入、 emplace方式插入
// 如果键不存在,则插入新元素;如果存在,则更新对应的值
myMap[4] = "four";
// 插入新的键值对
myMap.insert({5, "five"});
// 直接在map中构造新的元素
myMap.emplace(6, "six");
2、其他方式插入元素
#include <iostream>
#include <map>
int main()
{
std::map<int, std::string> myMap;
// 插入单个元素
myMap.insert(std::make_pair(1, "one"));
// 插入时使用结构化绑定(C++17 及以上)
auto [iterator, success] = myMap.insert({2, "two"});
if (success)
{
std::cout << "Insertion successful: " << iterator->first << " => " << iterator->second << std::endl;
}
else
{
std::cout << "Insertion failed, key already exists" << std::endl;
}
// 使用返回的迭代器
auto result = myMap.insert({3, "three"});
std::cout << "Inserted key: " << result.first->first << ", value: " << result.first->second << std::endl;
return 0;
}
四、查找元素
1、使用find函数
使用find方法进行查找对应的元素
// 返回一个迭代器指向键为3的元素
auto it = myMap.find(3);
if (it != myMap.end())
{
std::cout << "Key 3 has value: " << it->second << '\n';
}
else
{
std::cout << "Key 3 is not in the map.\n";
}
2、使用count函数
使用 count 方法进行查找,count 方法返回键出现的次数(对于 std::map,这个值要么是 0,要么是 1)
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<int, string> myMap = {{1, "one"}, {2, "two"}};
// 查找key对应的个数
if (myMap.count(2))
{
cout << "Key 2 exists in the map" << endl;
}
else
{
cout << "Key 2 does not exist in the map" << endl;
}
return 0;
}
五、删除元素
erase函数
// 根据键删除元素
myMap.erase(3);
// 根据迭代器删除元素
myMap.erase(it);
// 清空整个map
myMap.clear();
完整代码
#include <iostream>
#include <map>
int main()
{
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
// 根据键删除
myMap.erase(2);
// 根据迭代器删除
auto it = myMap.find(3);
if (it != myMap.end())
{
myMap.erase(it);
}
// 删除一个范围内的元素(删除所有)
myMap.erase(myMap.begin(), myMap.end());
return 0;
}
六、修改元素
可以通过键直接访问元素并修改其值
#include <iostream>
#include <map>
int main()
{
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}};
// 修改元素值
myMap[1] = "one updated";
std::cout << "Key: 1, Value: " << myMap[1] << std::endl;
return 0;
}
七、遍历元素
for (const auto& pair : myMap)
{
std::cout << "Key: " << pair.first << ", Value: " << pair.second << '\n';
}
// 或者使用迭代器
for (auto it = myMap.begin(); it != myMap.end(); ++it)
{
std::cout << "Key: " << it->first << ", Value: " << it->second << '\n';
}
八、其他用法
1、进阶用法,自定义比较函数
- 如果你希望以不同的方式排序键,可以提供一个自定义的比较函数或对象给 map
struct customCompare
{
bool operator()(const int& lhs, const int& rhs) const
{
return lhs > rhs; // 降序排序
}
};
std::map<int, std::string, customCompare> myCustomMap;
2、使用equal_range和count
- equal_range(key):返回一对迭代器,分别指向第一个不小于key的元素和第一个大于key的元素。
- count(key):返回指定键出现的次数。对于 map 和 multimap,这个值总是0或1,但对于 multiset 和 multimap 可能大于1。
auto range = myMap.equal_range(2);
for (auto it = range.first; it != range.second; ++it)
{
std::cout << "Key: " << it->first << ", Value: " << it->second << '\n';
}
int num = myMap.count(2); // 检查键2是否存在
九、总结
1、注意事项
- map 中的键是唯一的,如果你需要存储具有相同键的多个元素,应该考虑使用 multimap。
- 插入和删除操作可能会导致迭代器失效,尤其是在插入新元素时,如果新元素的插入位置位于已有的元素之前,那么所有指向后续元素的迭代器都会失效。
- 插入:可以使用 insert 或 operator[]。
- 删除:使用 erase。
- 修改:通过键直接访问元素并修改其值。
- 查找:使用 find、count 或 operator[]。
- 这些是 std::map 的基本操作,掌握这些操作可以高效地管理键值对数据