C++知识小屋(9):STL——map和multimap常用方法小结(包含pair对组的用法)

       STL在C++中起到非常重要的作用,最大的好处就是将常见的数据结构进行了封装,使得我们不需要从底层一步步去实现,使用起来非常方便。C++知识小屋🏠的STL系列旨在将常见STL库的常见函数进行小结,以函数+示例+结果展示的方式作为文章的整体结构。希望能够在用到这些库的时候能够快速上手,熟练地使用它们来解决一些常见的问题。

什么是map?

  • 现在设想一个问题,我们想要编写一个程序统计一个班级每个同学的成绩,比如叉烧同学是90分,大雄同学是100分,那么一种方法就是创建一个数组A,然后给每个同学编号,比如叉烧是1号,然后我们另A[1]=90,以此来达到存储的目的。
  • 但是当我们查询成绩的时候,这个方法会显得比较复杂,因为我们还需要根据数组的下标找到是哪一位同学,这样子就不够便捷,那么有没有一种方法,能够把同学的名字跟其分数直接对应起来呢?map正好解决了这个问题。
  • 我们可以创建一个map A< string,double >,表示这是一个从string类型映射到double类型的存储类型,然后我们令A[“叉烧”] = 90,A[“大雄”] = 100,这样子就能把每个同学直接跟其成绩直接储存在了A里面,这就是map的一个很常见的应用。你可能没看懂上面为什么要写< string,double >,没关系,下面正式来介绍map的用法。

map的用法

map的创建

  • 当我们想要使用需要在程序前面加上下面的库:
    #include <map>

  • map能够将任意两种类型构成一种映射关系,比如上面我们将同学的名字跟分数构成了映射关系,同学的名字是string类型,分数是double类型(可能有小数嘛),这样子当我们想要用map来储存这些映射关系的时候,就需要构造从string -> int 的映射,在代码中体现出来就是:
    map<string,int> A; //创建一个名字为A的map,映射关系为string->int

  • 需要注意的是,map是一对一的映射关系,比如上面的每个同学只有一个分数,如果我们对一个同学构造两个映射关系,则后面的会取代前面的。

map插入元素

  • 好了,上面我们创建了一个名字为A的map,下面我们想要往里面插入元素,要怎么做呢?下面介绍三种方法:
  1. A["叉烧"] = 90; 这是最简单也是最常用的一种方法,通过“[]”符号直接输入数据,比如我们想要把叉烧的分数是90分这条信息插入到A里面去,就在中括号里面写上叉烧,然后等号右边写上90分即可。你可能会问,为什么90分要写到等号右边呢?能不能把它们换个位置?这是不行的,因为map的定义就是从创建的时候左边的类型(string)映射到右边的类型(int),这个记住就好了。
  2. A.insert(pair<string,double>("胖虎",60));
  3. A.insert(make_pair("大雄",100));
    这里面用到了两个额外的知识点:pair与make_pair.

    什么是pair

    • 当我们想要在函数里面返回两个值的时候,就可以使用pair,它表示将两个数据组合成了一个数据。我们可以简单理解为pair就是一种包含两个东西的特殊类型就好了。
    • 关于pair的创建,跟map很相似,需要指定两个数据各自的类型,比如上面的胖虎是string类型,分数是double类型,然后我们就能直接创建pair对象pair<string,double>("胖虎",60)
    • 对于map的insert函数,由于需要传进去的是一个pair类型的对象,因此我们采用构造pair的方式传进去,进而达到我们的目的。

    什么是make_pair

    • 上面我们看到了pair对组的构造方法,我们需要指明两个数据的类型各自是什么。那么有没有办法更简单地创建pair对组呢?make_pair就是。
    • 从上面的第三种方法中我们make_pair不需要指明两种变量类型是什么,直接将我们的大雄和100分放进去即可,这样子可以说比普通的pair更简洁。

map常见信息查看

  • A.size() //查看map里面的元素个数
  • A.empty() //查看A是否为空
  • A["大雄"] //查看大雄对应的分数

查看map中是否包含某个key(count和find函数)

比如我们现在想看看A中是否包含叉烧这个变量,可以用下面的两种方法:

  1. 第一种使用count函数,里面写上我们要找的学生的名字,如果存在,则返回1,不存在则返回0
  2. 第二种是使用find函数,如果存在,返回的是一个迭代器,如果不存在,则返回map的end(),因此我们可以通过返回值是否为end()判断是否存在该元素。
cout << A.count("叉烧")  << endl;		//方法一:使用count函数,找不到则返回0

if(A.find("叉烧")!=A.end()){			//方法二:使用find函数,找不到则返回A.end()
		cout << 1 << endl;
	}

查看map中某个value对应的key

比如现在我们想要看分数为90分的是谁,可以遍历一遍map,然后找出是谁。

  • 注意:对于下面map的迭代器it,it->first表示的是key的值(学生名字),it->second表示的是value的值(学生的分数)
//寻找value对应的key 
for(map<string,int>::iterator it = A.begin();it!=A.end();it++){
	if(it->second == 90){
		cout << "分数为90分的同学有:" << it->first << endl;
	}	 

map完整程序

#include <iostream>
#include <map>
using namespace std;
int main(){
	//构造对象A (后面的两个'>'中间一定要有空格,否则会报错) 
	map<string,int> A;
	
	A["叉烧"] = 90;
	A.insert(make_pair("大雄",100));
	A.insert(pair<string,int>("胖虎",60));
	
	cout << "A中的元素个数为: " << A.size() << endl;
	cout << "A中是否为空: " << A.empty() << endl;	
	cout << "大雄的分数为" << A["大雄"] << endl;
	for(map<string,int>::iterator it = A.begin();it!=A.end();it++){
		cout << it->first << "  - >  " << it->second << endl;
	} 
	
	//查看A中是否包含叉烧的两种方法
	cout << "是否包含大雄: " << A.count("大雄") <<  endl << "是否包含叉烧: ";   
	if(A.find("叉烧")!=A.end()){
		cout << 1 << endl;
	}
	
	//寻找value对应的key 
	for(map<string,int>::iterator it = A.begin();it!=A.end();it++){
		if(it->second == 90){
			cout << "分数为90分的同学有:" << it->first << endl;
		}	
	} 
	return 0;
} 

在这里插入图片描述


multimap

  • 上面说的map只能表示1对1的映射,如果我们想要表示一对多的映射,则可以使用multimap,比如一个学生可以有多个成绩。
  • 与map一样,当我们想要使用需要在程序前面加上下面的库:
    #include <map>
  • 与map不一样的是,multimap不能使用“[]”的方式访问,也就是说当我们插入新元素的时候,不能够像map一样使用 A["叉烧"] = 90;的方法,只能使用insert的方式进行插入,同理当我们想要查看某位同学的分数,也不能像上面的A["大雄"] //查看大雄对应的分数一样,而是要使用迭代器的方式进行查看。
  • 当我们想要查看一位同学有几个分数的时候,可以使用count()函数进行查看,返回的值表示该同学一共在map中出现过多少次。
  • 当我们想要在map中删除某一位同学的信息的时候,可以使用erase(“同学的名字”).

程序演示

  • 下面的程序跟map的完整程序基本一样,不同之处如下:
    • 创建的时候由map变成了multimap
    • 删除了原先用"[]"访问的方法
    • 插入了两个叉烧同学的分数,并且在调用count函数的时候发现叉烧的值返回为2,表示叉烧在map中出现过两次。
    • 通过erase函数删除了叉烧同学的信息,然后输出发现叉烧同学的两个成绩都消失了,只剩下了胖虎的成绩。
#include <iostream>
#include <map>
using namespace std;

int main(){
	//构造multimap对象A (后面的两个'>'中间一定要有空格,否则会报错) 
	multimap<string,int> A;
	
	A.insert(make_pair("叉烧",90));
	A.insert(make_pair("叉烧",100));
	A.insert(pair<string,int>("胖虎",60));
	
	cout << "A中的元素个数为: " << A.size() << endl;
	cout << "A中是否为空: " << A.empty() << endl;	
	
	for(map<string,int>::iterator it = A.begin();it!=A.end();it++){
		cout << it->first << "  - >  " << it->second << endl;
	} 
	
	//查看A中是否包含叉烧的两种方法
	cout << "是否包含叉烧: " << A.count("叉烧") <<  endl << "是否包含叉烧: ";   
	if(A.find("叉烧")!=A.end()){
		cout << 1 << endl;
	}
	
	//寻找value对应的key 
	for(map<string,int>::iterator it = A.begin();it!=A.end();it++){
		if(it->second == 90){
			cout << "分数为90分的同学有:" << it->first << endl;
		}	 	
	} 
	
	A.erase("叉烧");
	cout << "删除叉烧后的map的信息为:" << endl; 
	for(map<string,int>::iterator it = A.begin();it!=A.end();it++){
		cout << it->first << "  - >  " << it->second << endl;
	} 	 
	return 0;
} 


在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值