map基于红黑树,有序且性能稳定,适用于需排序或范围查询的场景;unordered_map基于哈希表,平均操作为O(1),但无序且最坏情况为O(N),适合对性能敏感且无需排序的场景。选择时应根据是否需要键的顺序、性能要求及自定义类型的支持复杂度来决定。两者在API上相似,但底层机制不同,理解差异有助于高效编程。使用自定义类型作键时,map需定义正确的operator<或比较器以保证严格弱序,而unordered_map需提供哈希函数和operator==,并确保哈希一致性,否则会导致未定义行为。

C++ STL中的
map
unordered_map
map
unordered_map
std::map
std::unordered_map
std::map
map
#include <iostream>
#include <map>
#include <string>
void demonstrate_map() {
std::map<int, std::string> student_grades;
// 插入元素
student_grades[101] = "Alice"; // 推荐的插入方式之一
student_grades.insert({103, "Charlie"}); // C++11 initializer list
student_grades.insert(std::make_pair(102, "Bob")); // 使用std::make_pair
// 访问元素
std::cout << "Student 101: " << student_grades[101] << std::endl;
// 使用at()访问,如果键不存在会抛出std::out_of_range异常
try {
std::cout << "Student 104: " << student_grades.at(104) << std::endl;
} catch (const std::out_of_range& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
// 遍历map(元素按键有序输出)
std::cout << "Map contents (ordered by key):" << std::endl;
for (const auto& pair : student_grades) {
std::cout << "ID: " << pair.first << ", Name: " << pair.second << std::endl;
}
// 查找元素
auto it = student_grades.find(102);
if (it != student_grades.end()) {
std::cout << "Found student 102: " << it->second << std::endl;
} else {
std::cout << "Student 102 not found." << std::endl;
}
// 删除元素
student_grades.erase(101);
std::cout << "After deleting student 101, map size: " << student_grades.size() << std::endl;
}std::unordered_map
立即学习“C++免费学习笔记(深入)”;
#include <iostream>
#include <unordered_map>
#include <string>
void demonstrate_unordered_map() {
std::unordered_map<std::string, int> word_counts;
// 插入元素
word_counts["apple"] = 5;
word_counts.insert({"banana", 3});
word_counts["apple"]++; // 更新现有元素
// 访问元素
std::cout << "Count of apple: " << word_counts["apple"] << std::endl;
// 遍历unordered_map(元素顺序不确定)
std::cout << "Unordered Map contents:" << std::endl;
for (const auto& pair : word_counts) {
std::cout << "Word: " << pair.first << ", Count: " << pair.second << std::endl;
}
// 查找元素
auto it = word_counts.find("banana");
if (it != word_counts.end()) {
std::cout << "Found banana with count: " << it->second << std::endl;
}
// 删除元素
word_counts.erase("apple");
std::cout << "After deleting apple, map size: " << word_counts.size() << std::endl;
}
int main() {
std::cout << "--- Demonstrating std::map ---" << std::endl;
demonstrate_map();
std::cout << "\n--- Demonstrating std::unordered_map ---" << std::endl;
demonstrate_unordered_map();
return 0;
}map
unordered_map
选择
map
unordered_map
从底层机制来看,
map
unordered_map
性能差异:
std::map
log N
std::unordered_map
unordered_map
map
我的看法是,性能差异确实可能“非常大”,尤其是在处理大量数据时。一个O(1)的操作和O(log N)的操作,在N达到百万级别时,差距会是好几倍甚至几十倍。举个例子,如果N是100万,log₂(100万)大约是20。这意味着
map
unordered_map
unordered_map
map
如何选择?
lower_bound
upper_bound
map
unordered_map
unordered_map
map
map
unordered_map
我通常的经验是,如果对顺序没有特殊要求,我会倾向于先尝试
unordered_map
map
map
unordered_map
当我们将自定义的结构体或类作为
map
unordered_map
std::map
std::map
map
operator<
坑1:忘记或错误定义 operator<
operator<
operator<
operator<
a < b
b < a
a
b
map
Point
struct Point {
int x, y;
// 错误的operator< 定义:只比较x,如果x相同则认为是相等,但y可能不同
// 这样会导致 (1,5) 和 (1,10) 被认为是相等的,但它们实际不同
// bool operator<(const Point& other) const {
// return x < other.x;
// }
// 正确的operator< 定义:先比较x,x相同再比较y
bool operator<(const Point& other) const {
if (x != other.x) {
return x < other.x;
}
return y < other.y;
}
};
// 或者,你可以提供一个自定义的比较器作为map的模板参数
struct PointCmp {
bool operator()(const Point& a, const Point& b) const {
if (a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
};
// std::map<Point, std::string, PointCmp> myMap;建议: 始终确保你的
operator<
const
operator<=>
std::unordered_map
std::unordered_map
坑1:忘记或错误定义哈希函数。
unordered_map
std::hash<KeyType>
std::hash
Point
struct Point {
int x, y;
// unordered_map还需要这个来判断两个键是否真正相等
bool operator==(const Point& other) const {
return x == other.x && y == other.y;
}
};
// 方式一:特化std::hash
namespace std {
template <> struct hash<Point> {
std::size_t operator()(const Point& p) const {
// 一个简单的哈希组合方式,实际项目中可能需要更复杂的算法
// 这里使用std::hash对int进行哈希,然后异或组合
return std::hash<int>()(p.x) ^ (std::hash<int>()(p.y) << 1);
}
};
}
// 此时可以直接:std::unordered_map<Point, std::string> myUnorderedMap;
// 方式二:提供一个自定义哈希函数对象作为模板参数
struct PointHash {
std::size_t operator()(const Point& p) const {
return std::hash<int>()(p.x) ^ (std::hash<int>()(p.y) << 1);
}
};
// std::unordered_map<Point, std::string, PointHash> myUnorderedMap;建议: 确保哈希函数返回
std::size_t
unordered_map
坑2:忘记或错误定义 operator==
unordered_map
operator==
operator==
operator==
const
坑3:哈希函数与 operator==
a
b
operator==
a == b
std::hash<KeyType>()(a) == std::hash<KeyType>()(b)
unordered_map
以上就是C++STL映射map和unordered_map使用方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号