std::unordered_map 简单使用
2023-12-28 15:37:27
目录
std::unordered_map介绍
std::unordered_map
?是 C++ 标准库中的一种关联容器,用于实现键值对的存储和快速查找。它基于哈希表实现,具有以下特性:
特性:
- 快速查找:?由于底层使用哈希表,
std::unordered_map
?具有快速的查找性能。平均情况下,查找、插入和删除操作的时间复杂度为 O(1)。 - 无序性:?与?
std::map
?不同,std::unordered_map
?中的元素是无序的,即它们没有特定的顺序。如果需要有序性,应该使用?std::map
。 - 可变大小:?可以动态添加或删除键值对,而不需要提前指定容器的大小。
- 哈希冲突处理:?哈希表中可能会发生哈希冲突,
std::unordered_map
?采用开链法来处理冲突,即在每个哈希桶中维护一个链表。
优点:
- 快速查找:?对于大规模数据集,
std::unordered_map
?提供了快速的查找操作,使其成为高效的数据结构。 - 灵活性:?可以动态地插入和删除元素,适用于动态变化的数据集。
- 哈希表的均摊复杂度:?在理想情况下,哈希表的均摊复杂度为 O(1),提供了高效的性能。
缺点:
- 空间占用:?由于哈希表需要维护额外的空间来存储哈希桶和链表,可能会占用较多的内存空间。
- 不适合有序操作:?如果需要有序迭代或者按照键的顺序访问元素,
std::unordered_map
?不是最佳选择,应该考虑使用?std::map
。 - 性能不稳定:?在某些情况下,哈希表的性能可能会退化,导致查找、插入和删除操作的时间复杂度升高。
以下是?std::unordered_map
?的简单用法示例:
#include <iostream>
#include <unordered_map>
int main() {
// 创建一个 unordered_map
std::unordered_map<int, std::string> myMap;
// 插入键值对
myMap[1] = "One";
myMap[2] = "Two";
myMap[3] = "Three";
// 查找元素
auto it = myMap.find(2);
if (it != myMap.end()) {
std::cout << "Key 2 found, Value: " << it->second << std::endl;
} else {
std::cout << "Key 2 not found." << std::endl;
}
// 遍历 unordered_map
for (const auto& pair : myMap) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
return 0;
}
在这个例子中,我们创建了一个?std::unordered_map
,插入了一些键值对,并且演示了查找和遍历操作。std::unordered_map
?的初始化和赋值方式有多种,取决于使用的 C++ 版本和个人偏好。以下是一些常见的初始化和赋值方式:
初始化方式:
1. 直接初始化:
#include <unordered_map>
std::unordered_map<int, std::string> myMap1; // 默认构造函数,创建一个空的 unordered_map
std::unordered_map<int, std::string> myMap2 = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用初始化列表进行初始化
2. 复制初始化:
#include <unordered_map>
std::unordered_map<int, std::string> anotherMap(myMap2);
// 使用另一个 unordered_map 进行复制初始化
3. C++11 之后的 emplace 初始化:
#include <unordered_map>
std::unordered_map<int, std::string> myMap;
myMap.emplace(1, "One");
myMap.emplace(2, "Two");
// 使用 emplace 函数插入键值对
赋值方式:
1. 使用?operator[]
?进行赋值:
#include <unordered_map>
std::unordered_map<int, std::string> myMap;
myMap[1] = "One";
myMap[2] = "Two";
// 使用 operator[] 赋值
2. 使用?insert
?函数:
#include <unordered_map>
std::unordered_map<int, std::string> myMap;
myMap.insert({1, "One"});
myMap.insert(std::make_pair(2, "Two"));
// 使用 insert 函数插入键值对
3. 使用范围初始化:
#include <unordered_map>
#include <initializer_list>
std::unordered_map<int, std::string> myMap;
myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用初始化列表进行赋值
这些方式可以根据具体情况选择,初始化和赋值的方式可能会影响代码的可读性和性能。使用初始化列表的方式在 C++11 及更高版本中变得更加流行,因为它更简洁。
std::unordered_map
?的遍历方式有多种,以下是一些常见的遍历方式:
1. 使用迭代器遍历:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用迭代器遍历
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
}
return 0;
}
2. 使用范围-based for 循环遍历:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用范围-based for 循环遍历
for (const auto& pair : myMap) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
return 0;
}
3. 使用 C++11 之后的 auto 关键字:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用 auto 关键字
for (const auto& entry : myMap) {
std::cout << "Key: " << entry.first << ", Value: " << entry.second << std::endl;
}
return 0;
}
4. 使用?for_each
?算法(需要?<algorithm>
?头文件):
#include <iostream>
#include <unordered_map>
#include <algorithm>
void printKeyValue(const std::pair<int, std::string>& pair) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
int main() {
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用 for_each 算法
std::for_each(myMap.begin(), myMap.end(), printKeyValue);
return 0;
}
以上这些方式可以根据个人喜好和代码的上下文选择。使用范围-based for 循环和迭代器的方式是比较常见和直观的。
对于?std::unordered_map
,增删改查的方式可以通过以下方法实现:
增加元素:
1. 使用?operator[]
:
#include <unordered_map>
std::unordered_map<int, std::string> myMap;
myMap[1] = "One";
myMap[2] = "Two";
2. 使用?insert
?函数:
#include <unordered_map>
std::unordered_map<int, std::string> myMap;
myMap.insert({1, "One"});
myMap.insert(std::make_pair(2, "Two"));
3. 使用?emplace
?函数(C++11及更高版本):
#include <unordered_map>
std::unordered_map<int, std::string> myMap;
myMap.emplace(1, "One");
myMap.emplace(2, "Two");
删除元素:
1. 使用?erase
?函数:
#include <unordered_map>
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 删除指定键的元素
myMap.erase(2);
// 删除迭代器指向的元素
auto it = myMap.find(1);
if (it != myMap.end()) {
myMap.erase(it);
}
// 删除一定范围的元素
myMap.erase(myMap.begin(), myMap.end());
修改元素:
直接使用?operator[]
?或?insert
:
#include <unordered_map>
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 修改元素
myMap[2] = "NewTwo";
// 或者使用 insert 函数
myMap.insert({3, "NewThree"});
查找元素:
1. 使用?find
?函数:
#include <iostream>
#include <unordered_map>
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 查找元素
auto it = myMap.find(2);
if (it != myMap.end()) {
std::cout << "Key 2 found, Value: " << it->second << std::endl;
} else {
std::cout << "Key 2 not found." << std::endl;
}
2. 使用范围-based for 循环或迭代器遍历查找:
#include <iostream>
#include <unordered_map>
std::unordered_map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
// 使用范围-based for 循环
for (const auto& pair : myMap) {
if (pair.first == 2) {
std::cout << "Key 2 found, Value: " << pair.second << std::endl;
break;
}
}
// 使用迭代器
auto it = std::find_if(myMap.begin(), myMap.end(),
[](const auto& pair) { return pair.first == 2; });
if (it != myMap.end()) {
std::cout << "Key 2 found, Value: " << it->second << std::endl;
} else {
std::cout << "Key 2 not found." << std::endl;
}
上述代码演示了如何使用?std::unordered_map
?进行增删改查操作。选择适当的方法取决于具体的需求和代码上下文。
文章来源:https://blog.csdn.net/CHNIM/article/details/135268904
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!