【C++21天养成计划】映射类——快速上手STL map 和 multimap(Day17)

大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我热爱AI、热爱分享、热爱开源! 这博客是我对学习的一点总结与思考。如果您也对 深度学习、机器视觉、算法、Python、C++ 感兴趣,可以关注我的动态,我们一起学习,一起进步~
我的博客地址为:【AI 菌】的博客
我的Github项目地址是:【AI 菌】的Github


一、STL map 类简介

map 和 multimap 是键-值对容器,支持根据键进行查找,和数据结构中的字典类相似。

map 和 multimup 都是模板类,它们之间的区别在于,multimap 能够存储重复的键,而前者只能存储唯一的键。

为了实现快速查找,map 和 multimap 的内部结构看起来像棵二叉树。这意味着在 map 和 multimap 中插入元素时将进行排序。还意味着不能像vector那样可以使用其他元素替换给定位置的元素,位于map中特定位置的元素不能替换为值不同的新元素,这是因为map将把新元素同二叉树中的其他元素进行比较,进而将它放在其他的位置。

另外,需要注意的是,要使用STL map和 multimap类时,需要包含头文件:

# include<map>

在这里插入图片描述

二、map 和 multimap 类的基本操作

2.1 实例化操作

典型的 map 实例化语法如下:

map <keyType, valueType, Predicate=std::less <keyType> > mapObject;
multimap <keyType, valueType, Predicate=std::greater <keyType> >mmapObject;
  • 第一个参数keyType,代表的是键的类型
  • 第二个参数valueType,代表的是值的类型
  • 第三个参数less/greater,用作排序标准。less是升序排序,greater是降序排序。

下面使用了几种不同的方法,实例化了键值对{string, int}类型的 map 或 multimap。

#include <iostream>
#include <map>
#include <string>

using namespace std;
template<typename KeyType>

int main()
{
    
    
	// 方法1
    map<int, string> map1;
    multimap<int, string> mmap1;
	// 方法2
    map<int, string> map2(map1);
    multimap<int, string> mmap2(mmap1);
	// 方法3
    map<int, string> map3(map1.cbegin(), map1.cend());
    multimap<int, string> mmap3(mmap1.cbegin(), mmap1.cend());    

    return 0;
}

2.2 两种排序方式

在实例化 map 和 multimap 过程中,如果没有指定排序的词谓,那么 map 会默认对其内的元素进行升序排序

想要自定义map的排序标准,我们可以通过以下两种方法:

(1)使用map类默认提供的词谓 less 和 greater 来确定排序标准

// 1.升序 
map<int, string, less<int>> map1;
// 2.降序
multimap<int, string, greater<int>> mmap1;

(2)自定义词谓用作排序标准

#include <iostream>
#include <map>
#include <string>

using namespace std;
template<typename KeyType>

// 自定义词谓
struct ReverseSort
{
    
    
    bool operator()(const KeyType& key1, const KeyType& key2)
    {
    
    
        return (key1 > key2);
    }
};

int main()
{
    
    
	// 实例化
    map<int, string> map1;
    multimap<int, string> mmap1;
    
	// 降序排列
    map<int, string, ReverseSort<int>> map5(map1.cbegin(), map1.cend());
    multimap<int, string, ReverseSort<int>> mmap5(mmap1.cbegin(), mmap1.cend());
    
    return 0;
}

三、map 和 multimap 类的成员函数

2.1 插入元素函数 insert()

使用map的成员函数insert(),可以向map中插入新的键值对;下面演示了4种常用的插入方式:

#include <iostream>
#include <map>
#include <string>

using namespace std;
template <typename T>

// 显示内容
void DisplayContents(const T& Input)
{
    
    
    for(auto iElement = Input.cbegin(); iElement != Input.cend(); ++iElement)
        cout<<iElement->first<<"  "<<iElement->second<<endl;
    cout<<endl;
}

int main()
{
    
    
    map<int, string, less<int>>map1;
    // 插入方法1
    map1.insert(map<int, string>::value_type(3, "Three"));
    // 插入方法2
    map1.insert(make_pair(1, "One"));
    // 插入方法3
    map1.insert(pair<int, string>(10, "Ten"));
  
    // 插入方法4,采用类似于数组的语法进行插入。
    map1[8] = "Eight";

    cout<<"键 :值"<<endl;
    DisplayContents(map1);

    return 0;
}

进行类四次插入操作后,map里有四个键值对,显示如下:

在这里插入图片描述

2.2 查找元素函数find()

map 和 multimap 提供了成员函数find(),它能够根据给定的键查找值

find()返回的是一个迭代器,如下所示:

map1 <int, string>::const_iterator iFound = map1.find(Key);

使用find()进行查找元素时,要先检查迭代器,确保find()已成功,再使用它来访问找到的值

if(iFound != map1.end())
{
    
    
	cout<<"键 :值"<<endl;
	cout<<iFound->first<<" "<<iFound->second<<endl;
}
else
	cout<<"Key不存在于map中!"<<endl;

下面演示一个实际的例子, 使用成员函数find()查找map1中键所对应的值:

#include <iostream>
#include <map>
#include <string>

using namespace std;
template <typename T>

// 显示内容
void DisplayContents(const T& Input)
{
    
    
    for(auto iElement = Input.cbegin(); iElement != Input.cend(); ++iElement)
        cout<<iElement->first<<"  "<<iElement->second<<endl;
    cout<<endl;
}

int main()
{
    
    
    map<int, string, less<int>>map1;
    // 插入元素
    map1.insert(make_pair(8, "Eight"));
    map1.insert(make_pair(1, "One"));
    map1.insert(make_pair(6, "Six"));
    map1.insert(make_pair(10, "Ten"));
    // 显示键值
    cout<<"键 :值"<<endl;
    DisplayContents(map1);
    // 根据键查找其对应的值
    auto iFound = map1.find(8);
    if(iFound != map1.end())
        cout<<iFound->first<<"对应的值是:"<<iFound->second<<endl;
    else
        cout<<"Key不存在于map1中!"<<endl;

    return 0;
}

运行结果如下:
在这里插入图片描述
如果使用的是multimap,容器可能包含多个键相同的键值对,因此需要找到与指定键对应的所有值。所以,可先使用count()确定有多少个值与指定的键对应,再对迭代器递增,以访问所有对应的值。

下面的map存在3个相同的键值对,线要找到该键值对,并依次输出他们:

#include <iostream>
#include <map>
#include <string>

using namespace std;
template <typename T>

// 显示内容
void DisplayContents(const T& Input)
{
    
    
    for(auto iElement = Input.cbegin(); iElement != Input.cend(); ++iElement)
        cout<<iElement->first<<"  "<<iElement->second<<endl;
    cout<<endl;
}

int main()
{
    
    
    multimap<int, string, less<int>>map1;
    // 插入元素
    map1.insert(make_pair(8, "Eight"));
    map1.insert(make_pair(1, "One"));
    map1.insert(make_pair(8, "Eight"));
    map1.insert(make_pair(8, "Eight"));
    
    // 显示键值
    cout<<"键 :值"<<endl;
    DisplayContents(map1);

    // 根据键查找其所有对应的值
    auto iFound = map1.find(8);
    if(iFound != map1.end())
    {
    
    
        // 统计multimap中键8出现的次数
        size_t num = map1.count(8);
        for(size_t nCounter=0; nCounter<num; ++nCounter)
        {
    
    
            cout<<"Key: "<<iFound->first<<", Val["<<nCounter<<"]="<<iFound->second<<endl;
            ++iFound;
        }
    }
    else
        cout<<"Element Not Found In The Map!";

    return 0;
}

运行结果:
在这里插入图片描述

2.3 删除元素函数erase()

map 和 multimap 提供了成员函数erase(),该函数用于删除容器中的元素。主要有以下三种方法:

  • 将键作为参数时,这将删除包含指定键的所有键值对
map1.erase(key);
  • 以迭代器为参数,删除迭代器指向的参数
map1.erase(iFound);
  • 使用迭代器指定边界,删除指定范围内的所有元素
map1.erase(iLowerBound, iUpperBound);

下面实际演示以上三种方法的使用:

#include <iostream>
#include <map>
#include <string>

using namespace std;
template <typename T>

// 显示内容
void DisplayContents(const T& Input)
{
    
    
    for(auto iElement = Input.cbegin(); iElement != Input.cend(); ++iElement)
        cout<<iElement->first<<"  "<<iElement->second<<endl;
    cout<<endl;
}

int main()
{
    
    
    multimap<int, string, less<int>>map1;
    // 插入元素
    map1.insert(make_pair(8, "Eight"));
    map1.insert(make_pair(1, "One"));
    map1.insert(make_pair(6, "Six"));
    map1.insert(make_pair(10, "Ten"));
    map1.insert(make_pair(15, "Fifteen"));


    // 显示键值
    cout<<"键 :值"<<endl;
    DisplayContents(map1);

    // 删除键1对应的键值对
    map1.erase(1);
    cout<<"删除键1对应的键值对后:"<<endl;
    DisplayContents(map1);

    // 删除迭代器指向的元素
    auto iFound = map1.find(8);
    map1.erase(iFound);
    cout<<"删除键8对应的键值对后:"<<endl;
    DisplayContents(map1);

    // 删除指定范围内(6至10)的元素
    map1.erase(map1.lower_bound(6), map1.lower_bound(15));
    cout<<"删除指定范围内(从6开始,到15之前)的元素:"<<endl;
    DisplayContents(map1);

    return 0;
}

运行结果:
在这里插入图片描述


今天的分享就到这里啦,希望对你的学习有所帮助!

在这里插入图片描述

最后,我有幸入选了CSDN原创博客大赛Top50,如果您能为我投出宝贵的一票,将是对我创作的最大鼓励!投票完后还能参与官方抽奖哟!

投票通道:CSDN原创博客大赛
在这里插入图片描述

养成习惯,先赞后看!你的支持是我创作的最大动力!

猜你喜欢

转载自blog.csdn.net/wjinjie/article/details/108710213