c++里面unordered_map的操作
时间: 2025-07-29 21:27:30 AIGC 浏览: 17
<think>我们正在讨论的是unordered_map,它是C++STL中的一个关联容器,基于哈希表实现。以下将按照常用操作分类进行说明,并参考用户提供的引用内容。###一、头文件与初始化```cpp#include<unordered_map>//必须包含的头文件#include<string>usingnamespacestd;intmain(){//1.空unordered_mapunordered_map<string,int>emptyMap;//2.列表初始化(C++11及以上)unordered_map<string,int>fruitMap={{"apple",5},{"banana",3},{"orange",8}};//3.使用数组语法初始化(注意:这不是标准初始化,而是后续赋值)unordered_map<int,string>idMap;idMap[1]="Alice";idMap[2]="Bob";}```###二、元素插入```cppunordered_map<string,int>myMap;//1.insert方法(返回pair<iterator,bool>)autoret=myMap.insert({"apple",5});if(ret.second){cout<<"插入成功"<<endl;}else{cout<<"键已存在"<<endl;}//2.数组下标插入(若键存在则覆盖值)myMap["banana"]=3;//插入新键值对myMap["apple"]=10;//覆盖已存在的键的值//3.emplace方法(原地构造,高效)myMap.emplace("orange",8);//避免临时对象构造//4.插入多个元素(C++11)myMap.insert({{"grape",20},{"pear",15}});```###三、元素访问```cppunordered_map<string,int>myMap={{"apple",5},{"banana",3}};//1.数组下标访问(不存在时自动插入并默认初始化)cout<<myMap["apple"];//输出5cout<<myMap["mango"];//不存在,创建{"mango",0},输出0//2.at方法(安全访问,不存在时抛出out_of_range)try{cout<<myMap.at("banana");//3cout<<myMap.at("kiwi");//抛出异常}catch(constout_of_range&e){cerr<<"键不存在:"<<e.what()<<endl;}//3.使用find方法(推荐,避免意外插入)autoit=myMap.find("apple");if(it!=myMap.end()){cout<<it->second;//访问值}else{cout<<"未找到";}```###四、元素删除```cppunordered_map<string,int>myMap={{"apple",5},{"banana",3},{"orange",8}};//1.erase通过键删除size_tcount=myMap.erase("apple");//返回删除数量(0或1)//2.erase通过迭代器删除autoit=myMap.find("banana");if(it!=myMap.end()){myMap.erase(it);//直接删除迭代器指向元素}//3.erase删除范围(C++11)autoit1=myMap.find("orange");if(it1!=myMap.end()){//删除从it1到末尾(实际只有一个元素)myMap.erase(it1,myMap.end());}//4.清空整个容器myMap.clear();```###五、遍历方法```cppunordered_map<string,int>myMap={{"apple",5},{"banana",3}};//1.基于范围的for循环(C++11)for(constauto&pair:myMap){cout<<pair.first<<":"<<pair.second<<endl;}//2.使用迭代器for(autoit=myMap.begin();it!=myMap.end();++it){cout<<it->first<<"->"<<it->second<<endl;}//3.结构化绑定(C++17)for(constauto&[key,value]:myMap){cout<<key<<"="<<value<<endl;}```###六、容量查询```cppunordered_map<string,int>myMap;cout<<"是否为空:"<<myMap.empty()<<endl;//1(true)cout<<"元素数量:"<<myMap.size()<<endl;//0myMap.emplace("test",1);cout<<"桶数量:"<<myMap.bucket_count()<<endl;//哈希桶总数cout<<"负载因子:"<<myMap.load_factor()<<endl;//元素数/桶数```###七、高级特性(C++11/14/17/20)```cpp//1.C++20contains方法(检查键是否存在)if(myMap.contains("apple")){//返回boolcout<<"存在apple键"<<endl;}//2.C++17节点操作(无拷贝转移)unordered_map<int,string>map1,map2;map1.emplace(1,"one");autonode=map1.extract(1);//提取节点if(!node.empty()){map2.insert(std::move(node));//转移插入}//3.C++14异构查找(避免临时对象构造)//定义自定义哈希器(允许string_view查找)structstring_hash{usingis_transparent=void;//关键:启用透明比较size_toperator()(string_viewsv)const{returnhash<string_view>()(sv);}};unordered_map<string,int,string_hash,equal_to<>>dict;dict["apple"]=5;if(dict.contains("apple"sv)){//使用string_view查找cout<<"找到apple"<<endl;}```###八、注意事项1.**键的唯一性**:每个键在容器中唯一(重复插入会失败或覆盖)2.**哈希冲突**:性能依赖于哈希函数质量(自定义类型需特化`std::hash`)3.**迭代器失效**:-插入元素可能导致重哈希,使所有迭代器失效-删除元素仅使被删元素的迭代器失效4.**自定义键类型**:```cppstructMyKey{intid;stringname;};//必须定义哈希函数和相等比较namespacestd{template<>structhash<MyKey>{size_toperator()(constMyKey&k)const{returnhash<int>()(k.id)^hash<string>()(k.name);}};template<>structequal_to<MyKey>{booloperator()(constMyKey&a,constMyKey&b)const{returna.id==b.id&&a.name==b.name;}};}```>完整示例参考引用[1][3][4],所有操作需包含头文件:`#include<unordered_map>`§§相关问题§§1.unordered_map与map在性能上有何区别?如何选择?2.如何为自定义类型实现哈希函数?3.C++17的节点操作如何提升性能?4.unordered_map的负载因子如何影响性能?如何调整?</think>### C++ unordered_map 常用操作指南
`unordered_map` 是 C++ 标准库中的哈希表实现,提供 $O(1)$ 平均时间复杂度的键值对操作。以下是核心操作分类和示例:
#### 一、头文件与初始化
```cpp
#include <unordered_map> // 必须包含的头文件
#include <string>
using namespace std;
// 1. 空unordered_map
unordered_map<string, int> emptyMap;
// 2. 列表初始化 (C++11及以上)
unordered_map<string, int> fruitMap = {
{"apple", 5},
{"banana", 3},
{"orange", 8}
};
// 3. 使用数组语法初始化
unordered_map<int, string> idMap;
idMap[1] = "Alice";
idMap[2] = "Bob";
```
#### 二、元素插入
```cpp
unordered_map<string, int> myMap;
// 1. insert方法(返回pair<iterator, bool>)
auto ret = myMap.insert({"apple", 5});
if (ret.second) {
cout << "插入成功" << endl;
} else {
cout << "键已存在" << endl;
}
// 2. 数组下标插入(若键存在则覆盖值)
myMap["banana"] = 3; // 插入新键值对
myMap["apple"] = 10; // 覆盖已存在的键的值
// 3. emplace方法(原地构造,高效)
myMap.emplace("orange", 8); // 避免临时对象构造
```
#### 三、元素访问
```cpp
unordered_map<string, int> myMap = {{"apple", 5}, {"banana", 3}};
// 1. 数组下标访问(不存在时自动插入)
cout << myMap["apple"]; // 输出5
cout << myMap["mango"]; // 不存在,创建{"mango",0},输出0
// 2. at方法(安全访问,不存在时抛出异常)
try {
cout << myMap.at("banana"); // 3
cout << myMap.at("kiwi"); // 抛出out_of_range
} catch (const out_of_range& e) {
cerr << "键不存在: " << e.what() << endl;
}
// 3. 使用find方法(推荐,避免意外插入)
auto it = myMap.find("apple");
if (it != myMap.end()) {
cout << it->second; // 访问值
}
```
#### 四、元素删除
```cpp
unordered_map<string, int> myMap = {{"apple",5}, {"banana",3}, {"orange",8}};
// 1. erase通过键删除
size_t count = myMap.erase("apple"); // 返回删除数量(0或1)
// 2. erase通过迭代器删除
auto it = myMap.find("banana");
if (it != myMap.end()) {
myMap.erase(it);
}
// 3. 清空容器
myMap.clear();
```
#### 五、遍历方法
```cpp
unordered_map<string, int> myMap = {{"apple",5}, {"banana",3}};
// 1. 基于范围的for循环(C++11)
for (const auto& pair : myMap) {
cout << pair.first << ": " << pair.second << endl;
}
// 2. 使用迭代器
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
cout << it->first << "->" << it->second << endl;
}
// 3. 结构化绑定(C++17)
for (const auto& [key, value] : myMap) {
cout << key << " = " << value << endl;
}
```
#### 六、容量查询
```cpp
unordered_map<string, int> myMap;
cout << "是否为空: " << myMap.empty() << endl; // 1 (true)
cout << "元素数量: " << myMap.size() << endl; // 0
myMap.emplace("test", 1);
cout << "桶数量: " << myMap.bucket_count() << endl; // 哈希桶总数
cout << "负载因子: " << myMap.load_factor() << endl; // 元素数/桶数
```
#### 七、高级特性
```cpp
// 1. C++20 contains方法(检查键是否存在)
if (myMap.contains("apple")) { // 返回bool
cout << "存在apple键" << endl;
}
// 2. C++17节点操作(无拷贝转移)
unordered_map<int, string> map1, map2;
map1.emplace(1, "one");
auto node = map1.extract(1); // 提取节点
if (!node.empty()) {
map2.insert(std::move(node)); // 转移插入
}
// 3. C++14异构查找(避免临时对象构造)
struct string_hash {
using is_transparent = void; // 关键:启用透明比较
size_t operator()(string_view sv) const {
return hash<string_view>()(sv);
}
};
unordered_map<string, int, string_hash, equal_to<>> dict;
dict["apple"] = 5;
if (dict.contains("apple"sv)) { // 使用string_view查找
cout << "找到apple" << endl;
}
```
#### 八、注意事项
1. **键的唯一性**:每个键在容器中唯一(重复插入会失败或覆盖)
2. **哈希冲突**:性能依赖于哈希函数质量(自定义类型需特化`std::hash`)
3. **迭代器失效**:
- 插入元素可能导致重哈希,使所有迭代器失效
- 删除元素仅使被删元素的迭代器失效
4. **自定义键类型**:
```cpp
struct MyKey {
int id;
string name;
};
// 必须定义哈希函数和相等比较
namespace std {
template<>
struct hash<MyKey> {
size_t operator()(const MyKey& k) const {
return hash<int>()(k.id) ^ hash<string>()(k.name);
}
};
}
```
> 完整示例参考引用[1][3][4],所有操作需包含头文件:`#include <unordered_map>`
阅读全文
相关推荐



















