C++——容器(map)

在C++中,map、multimap和unordered_map是三种不同的容器,用于存储键值对。它们各自有不同的特点和适用场景。

std::map:

基于红黑树实现的有序关联容器,以键的顺序进行存储和访问。

每个键只能对应一个值。

插入和查找操作的平均时间复杂度为O(logN),其中N是元素数量。

适用于需要有序存储和根据键进行快速查找的场景。

std::multimap:

基于红黑树实现的有序关联容器,以键的顺序进行存储和访问。

允许一个键对应多个值,即允许重复键。

插入和查找操作的平均时间复杂度为O(logN),其中N是元素数量。

适用于需要有序存储、允许重复键和根据键进行快速查找的场景。

std::unordered_map:

基于哈希表实现的无序关联容器,元素存储顺序不固定。

每个键只能对应一个值。

插入和查找操作的平均时间复杂度为O(1),最坏情况下为O(N),其中N是元素数量。

适用于需要快速插入、查找和不需要元素有序存储的场景。

通用操作:

1、插入元素:
#include <map> //map 和 multimap容器的头文件
#include<unordered_map> //unordered_map容器的头文件

// 容器的类型可以改为:std::multimap std::unordered_map
std::map<KeyType, ValueType> myMap;
myMap.insert(std::make_pair(key, value)); // 插入键值对
myMap[key] = value; // 使用下标操作符插入键值对

2、访问和修改元素:
ValueType value = myMap[key]; // 使用键访问对应的值
myMap[key] = newValue; // 修改指定键的值


3、查找元素:
auto iter = myMap.find(key); // 使用find函数根据键查找元素
if (iter != myMap.end()) {
    // 键存在,可以访问对应的值
    ValueType value = iter->second;
}

mulitmap容器中存在一个键值对应多个值的问题,因此查找元素略有不同:
auto range = myMultimap.equal_range(key); // 查找与键匹配的元素范围
for (auto iter = range.first; iter != range.second; ++iter) {
    // 对范围内的元素进行操作
}

4、删除元素:
myMap.erase(key); // 根据键删除对应的元素

5、遍历容器:
for (const auto& pair : myMap) {
    KeyType key = pair.first;
    ValueType value = pair.second;
    // 对每个键值对进行操作
}

6、获取容器大小
std::size_t size = myMap.size(); // 获取`std::unordered_map`中键值对的数量

### C++ STL Set 和 Map 的使用方法 #### 关于 `std::set` `std::set` 是一种关联容器,存储唯一键值并自动按升序排列。为了支持自定义类型的元素,需确保该类型能通过 `<` 或其他指定的方式进行比较。 ```cpp // 创建一个标准的 set,默认按照从小到大排序 std::set<int> intSet; intSet.insert(10); intSet.insert(20); intSet.insert(5); for (const auto& elem : intSet) { std::cout << elem << ' '; } ``` 当涉及到更复杂的数据结构或者想要改变默认排序方式时,可以通过提供第二个模板参数来自定义比较逻辑[^3]: ```cpp struct CustomCompare { bool operator()(const MyType& lhs, const MyType& rhs) const; }; std::set<MyType, CustomCompare> customSet; ``` 对于允许重复元素的情况,则应考虑使用 `std::multiset` 而不是普通的 `std::set`。 #### 关于 `std::map` `std::map` 同样是一个有序映射表,其中每个元素都是由唯一的键及其对应的值组成的一对儿。同样地,在处理非内置数据类型作为键的时候,可能需要重载小于运算符 (`<`) 以满足内部红黑树的要求[^1]。 下面给出一段基于字符串数组统计词频的例子代码片段[^2]: ```cpp void test_map3() { std::string str[] = {"sort", "sort", "tree", "insert", "sort", "tree", "sort", "test"}; std::map<std::string, int> countMap; // 统计字符串个数 for (auto& e : str) { auto ret = countMap.find(e); // 返回一个迭代器 if (ret == countMap.end()) { // 如果不存在,则插入 countMap[e] = 1; } else { // 如果存在,则次数++ ++ret->second; } } for (auto& kv : countMap) { std::cout << kv.first << " " << kv.second << '\n'; } } ``` 值得注意的是,上述例子中的查找操作可以直接简化为利用下标运算符来进行赋值或更新频率的操作,即 `countMap[e] += 1;`,这样可以省略显式的判断过程。 #### 总结 无论是 `std::set` 还是 `std::map` 都提供了强大的功能来管理和查询大量具有特定顺序关系的信息集合。理解如何正确配置这些容器的关键在于掌握好它们所依赖的基础概念——比如键值对比机制以及内存管理策略等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值