C++ 标准模板库 STL(2)map 与 multimap

一、简介

        map和multimap是键-值对容器,支持根据键进行查找。二者的区别在于后者能够存储重复的键,而前者只能存储唯一的键。

        map与multimap插入元素与上一节的容器相似,都会在插入元素时进行排序。

二、基本操作

2.1 头文件

#include <map>

2.2 初始化

        初始化map或multimap时,需要指定键和值的类型以及排序函数,排序函数默认是std::less,即升序排列。当然也可以使用自定义的比较函数来实现排序。

#include <map>
#include <string>

using namespace std;

// 降序排列
template <typename T>
struct ReverseSort {
    bool operator() (const T& k1, const T& k2) {
        return k1 > k2;
    }
};

int main() {
    // 使用默认排序方式初始化
    map<int, string> mapIntToStr1;
    multimap<int, string> mmapIntToStr1;

    // 使用自定义排序方式初始化
    map<int, string, ReverseSort<int>> mapIntToStr2;
    multimap<int, string, ReverseSort<int>> mmapIntToStr2;

    // 使用复制构造函数初始化
    map<int, string> mapIntToStr3(mapIntToStr1);
    
    // 使用迭代器初始化
    map<int, string> mapIntToStr4(mapIntToStr1.cbegin(), mapIntToStr1.cend());

    return 0;
}

2.3 插入元素

        使用insert()函数能够向map或multimap容器中插入元素。insert()函数的具体使用可以按照如下方式:

using namespace std;

map<int, std::string> mapIntToStr1;

mapIntToStr1.insert(make_pair(1, "One"));

mapIntToStr1.insert(pair<int, string>(1, "One"));

2.4 查找元素

        使用find()函数能够查找给定键值对应的值,返回一个迭代器。

using namespace std;

// 返回类型为迭代器
map<int, string>::const_iterator pairFound = mapIntToStr1.find(1);
// 对于C++11新增了自动判断类型可以使用auto来简写
auto pairFound = mapIntToStr1.find(1);

if (pairFound != mapIntToStr1.end()) {
    cout << pairFound->first << ", " << pairFound->second << endl;
} else {
    cout << "Key Not Found" << endl;
}

        对于multimap容器,可能包含相同键值对应多个值的情况,可以使用count()来确定有多少个值对应相同的键,而后再对迭代器递增从而访问相邻的值。

auto pairFound = mmapIntToStr.find(1);

if (pairFound != mmapIntToStr.end()) {
    size_t numberPairs = mmapIntToStr.count(1);
    for (size_t i=0; i<numberPairs; i++) {
        cout << pairFound->first << ", " << pairFound->second << endl;
        pairFound++;
    }
} else {
    cout << "Key not found" << endl;
}

2.5 删除元素

        使用erase()删除容器中的元素。

// 1. 根据键直接删除, 这将删除multimap中所有键为1的键-值对
mmapIntToStr.erase(1);

// 2. 根据迭代器删除
auto pairFound = mmapIntToStr.find(45);
if (pairFound != mmapIntToStr.end()) {
    mmapIntToStr.erase(pairFound);
}

三、基于散列表的STL键-值对容器

        unordered_map的平均插入和删除时间是固定的,查找元素的时间也是固定的。unordered_map容器是C++11引入的,与map和multimap差别不大,可以使用类似的方式实现实例化、插入和查找。

        但绝对不要编写依赖于unordered_map中元素排列顺序的代码。因为unordered_map是无序的,与map的有序不一样。

        在不发生冲突的情况下,unordered_map容器的插入和查找时间几乎是固定的,不受包含的元素数的影响。然而,这并不意味着它优于在各种情形下复杂度都为对数的map容器。在包含的元素不太多的情况下,固定时间可能长的多,导致unordered_map速度比map要慢。

四、总结

        需要键-值对唯一时,务必使用map或者unordered_map。但如果键值可能重复时务必使用multimap或者unordered_multimap。如果需要插入和查找时间固定时,务必使用unordered_map或者unordered_multimap。

        本章介绍了STL中的map与multimap的用法以及重要成员函数。这些容器插入和查找的时间复杂度为O(logn)。对于unordered_map和unordered_multimap容器,它们的插入和查找性能不受容器大小的影响。

  • 19
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值