map、set、multimap、multiset有什么区别?
参考回答
map
、set
、multimap
和 multiset
是 C++ STL 中的关联容器,底层均基于 红黑树 实现。它们的主要区别在于是否存储键值对、是否允许键重复、以及操作方式的差异。
主要区别:
- 键值对存储:
map
和multimap
存储键值对 (key-value
)。set
和multiset
只存储键 (key
)。
- 键的唯一性:
map
和set
中的键是唯一的。multimap
和multiset
允许键重复。
- 常见操作:
map
和set
适合需要快速查找唯一键的场景。multimap
和multiset
适合需要存储重复键的场景。
详细讲解与拓展
1. map
- 特点:
- 存储唯一的键值对 (
key-value
)。 - 自动按照键排序(默认升序)。
- 可以通过键快速查找对应的值。
- 存储唯一的键值对 (
- 示例:
#include <map>
#include <iostream>
using namespace std;
int main() {
map<int, string> myMap;
myMap[1] = "One";
myMap[2] = "Two";
myMap[1] = "New One"; // 键 1 的值被更新
for (const auto& [key, value] : myMap) {
cout << key << ": " << value << endl;
}
return 0;
}
输出:
1: New One
2: Two
- 适用场景:
适用于需要快速查找唯一键和值的场景,例如存储配置项、字典等。
2. set
- 特点:
- 只存储唯一的键 (
key
)。 - 自动按照键排序(默认升序)。
- 不支持重复键的插入。
- 只存储唯一的键 (
- 示例:
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> mySet = {10, 20, 30};
mySet.insert(20); // 插入失败,键已存在
mySet.insert(40); // 插入成功
for (int val : mySet) {
cout << val << " ";
}
return 0;
}
输出:
10 20 30 40
- 适用场景:
适用于需要快速查找唯一元素的场景,例如集合操作、不重复的记录存储等。
3. multimap
- 特点:
- 存储键值对 (
key-value
)。 - 允许键重复,多个相同的键可以有不同的值。
- 自动按照键排序(默认升序)。
- 存储键值对 (
- 示例:
#include <map>
#include <iostream>
using namespace std;
int main() {
multimap<int, string> myMultimap;
myMultimap.insert({1, "One"});
myMultimap.insert({2, "Two"});
myMultimap.insert({1, "Another One"}); // 键 1 可以重复
for (const auto& [key, value] : myMultimap) {
cout << key << ": " << value << endl;
}
return 0;
}
输出:
1: One
1: Another One
2: Two
- 适用场景:
适用于需要存储重复键的场景,例如分类存储数据、映射多个值到同一键等。
4. multiset
- 特点:
- 只存储键 (
key
)。 - 允许键重复,且自动按照键排序(默认升序)。
- 常用于统计或存储重复数据。
- 只存储键 (
- 示例:
#include <set>
#include <iostream>
using namespace std;
int main() {
multiset<int> myMultiset = {10, 20, 10};
myMultiset.insert(10); // 键 10 可以重复
for (int val : myMultiset) {
cout << val << " ";
}
return 0;
}
输出:
10 10 10 20
- 适用场景:
适用于需要存储重复元素的场景,例如统计频率、处理多重集合等。
5. 功能对比总结
容器 | 是否存储键值对 | 是否允许键重复 | 自动排序 | 查找时间复杂度 | 典型操作 |
---|---|---|---|---|---|
map |
是(key-value ) |
否 | 是(升序) | (O(\log n)) | 单键查找、更新 |
set |
否(key ) |
否 | 是(升序) | (O(\log n)) | 唯一集合 |
multimap |
是(key-value ) |
是 | 是(升序) | (O(\log n)) | 重复键分组存储 |
multiset |
否(key ) |
是 | 是(升序) | (O(\log n)) | 重复元素统计 |
6. 应用场景总结
map
:- 存储唯一键值对,例如配置项或字典。
- 快速查找键对应的值。
set
:- 唯一元素集合,例如防止重复数据或快速判断某个值是否存在。
multimap
:- 允许多个值对应同一键,例如按类别分组存储。
multiset
:- 统计元素出现次数,例如频率统计、多重集合的处理。
总结
map
、set
、multimap
和 multiset
的主要区别在于是否存储键值对、是否允许键重复以及应用场景不同。理解它们的底层实现(红黑树)和特性,可以在实际开发中根据需求选择合适的容器。如果不需要排序且追求更高性能,可以考虑它们的无序版本(如 unordered_map
和 unordered_set
)。