map的常用用法(STL库)

map翻译为映射,也是常用的STL容器。在定义数组时,其实是定义了一个int型到其他型的映射如int arry[100],其实就是定义了一个从int型到int型的映射,比如arry[0]=20,arry[1]=30就分别是将0映射到20,1映射到30。它有一个弊端,当需要以其他类型作为关键字是时,就不太容易操作。比如有一本字典,上面由很多单词与单词对应的页码,若用数组表示“单词-->页码”的对应关系,就很难做到。这时就可以用到map,因为map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器),也就可以建立string型到int型的映射。

还可以来看这样一个情况,这次需要判断给定的一些数字在某个文件是否出现过。按照以前所学,可以开一个bool型的hashTable[max_size],通过判断hashTable[x]为true还是false来确定x是否在文件中出现过。但会碰到一个问题,如果这些数字很大(例如有几千位),那么这个数组可能就会开不了了。而这时map就可以派上用场了,因为map可以将这些数字当成一些字符串,然后建立string到int的映射(或者直接建立int到int的映射?)。

如果要使用map,需要添加map的头文件 #include<map>,并且在头文件下加 using namespace std; 。

 

1、map的定义

单独定义一个map:

map<typename1, typename2> mp;

map和其他STL容器在定义上有点不一样,因为map需要确定映射前类型(键key)和映射后类型(值value),所以需要在<>内填写两个类型,其中第一个时键的类型,第二个时值的类型。如果时int到int型,就相当于普通的int数组。

如果是字符串到整型的映射,必须使用string而不能用char数组,这是因为char数组作为数组,是不能被作为键值的。

map<string,int> mp;

前面也说到,map的键和值也可以是STL容器,例如可以将一个set容器映射到一个字符串:

map<set<int>,string>;

 

2、map容器内元素的访问

map一般有两种访问方式,通过迭代器或者通过下标访问。

(1)通过下标访问

和访问普通的数组时一样的,例如对于一个定义为map<char,int> mp的map来说,就可以直接使用map['c']的方式来访问它对应的整数。于是,当建立映射时,就可以直接使用mp['c']=20,这样和数组一样的方式。但要注意,map中的键时唯一的。

#include<cstdio>
#include<map>
using namespace std;
int main(){
	map<char,int> mp;
	mp['c']=20; 
	mp['c']=30;  //map中键时唯一的,20会被覆盖 
	printf("%d",mp['c']);  //输出30 
	return 0;
} 

 

(2)通过迭代器访问

map迭代器的定义和其他STL容器迭代器的方式相同:

map<typename1,  typename2> :: iterator  it;

typename1,typename2就是定义map时填写的类型,这样就得到了迭代器it

map迭代器的使用和其他STL容器的迭代器不同,因为map的每一对映射都有两个typename,这决定了必须通过一个it来同时访问键和值,map可以使用 it->first来访问键,使用it->second来访问值

示例:

#include<cstdio> 
#include<map>
using namespace std;
int main(){
	map<char,int> mp;
	mp['m']=20;
	mp['a']=30;
	mp['r']=40;
	
	for(map<char,int>::iterator it =mp.begin(); it!=mp.end(); it++){
		printf("%c %d\n",it->first,it->second);
	}
	return 0;
}

输出:

由输出结果发现,map会以键从小到大的顺序自动排序,即按 a<m<r 的顺序排列这三对映射。这是由于map内部的红黑树实现的(set也是),在建立映射的过程中会自动实现从小到大的排序功能。

 

3、map常用函数示例

(1)find( )

find(key)返回键为key的映射的迭代器,时间复杂度为O(logN),N为map中映射的个数。

示例:

#include<cstdio>
#include<map>
using namespace std; 
int main(){
	map<char, int> mp;
	mp['a']=1;
	mp['b']=2;
	mp['c']=3;
	map<char,int>::iterator it=mp.find('b');
	printf("%c  %d\n",it->first,it->second);
	return 0;
}

输出结果:

 

(2)erase( )

erase( )有两种用法:删除单个元素、删除一个区间内所有元素。

①删除单个元素

删除单个元素有两种方法:

  • mp.erase(it),it为需要删除的元素的迭代器。时间复杂度为O(1)。

示例:

#include<cstdio>
#include<map>
using namespace std; 
int main(){
	map<char, int> mp;
	mp['a']=1;
	mp['b']=2;
	mp['c']=3;
	
	map<char,int>::iterator it=mp.find('b');
	
	mp.erase(it); //删除 b,2 
	for(map<char,int>::iterator it=mp.begin(); it !=mp.end(); it++)
		printf("%c  %d\n",it->first,it->second);
	return 0;
}

输出:

 

  • mp.erase(key),key为欲删除的映射的键。时间复杂度为O(logN),N为map内元素的个数。

示例:

#include<cstdio>
#include<map>
using namespace std; 
int main(){
	map<char, int> mp;
	mp['a']=1;
	mp['b']=2;
	mp['c']=3;
	
	//map<char,int>::iterator it=mp.find('b');	
	mp.erase('b'); //删除 键为b的映射, 即 b 2 
	
	for(map<char,int>::iterator it=mp.begin(); it !=mp.end(); it++)
		printf("%c  %d\n",it->first,it->second);
	return 0;
}

输出:

 

②删除一个区间内的所有元素

mp.erase(first,last);  其中first为需要删除的区间的起始迭代器,而last则为需要删除的区间的末尾迭代器的下一个地址,也即为删除左闭右开的区间 [first,last) 。时间复杂度为O(last-first)。

示例:

#include<cstdio>
#include<map>
using namespace std; 
int main(){
	map<char, int> mp;
	mp['a']=1;
	mp['b']=2;
	mp['c']=3;
	
	map<char,int>::iterator it=mp.find('b'); //令it指向键为b的映射 
	mp.erase(it,mp.end()); //删除it后的所有映射,即 b 2和 c 3 
	
	for(map<char,int>::iterator it=mp.begin(); it !=mp.end(); it++)
		printf("%c  %d\n",it->first,it->second);
	return 0;
}

输出:

 

(3)size( )

size( )用来获取map中映射的对数,时间复杂度为O(1)。

示例:

#include<cstdio>
#include<map>
using namespace std; 
int main(){
	map<char, int> mp;
	mp['a']=1;
	mp['b']=2;
	mp['c']=3;
	
	printf("%d\n",mp.size());
	return 0;
}

输出:

 

(4)clear( )

clear( )用来清空map中的所有元素,复杂度为O(N),其中N为map中元素的个数。

示例:

#include<cstdio>
#include<map>
using namespace std; 
int main(){
	map<char, int> mp;
	mp['a']=1;
	mp['b']=2;
	mp['c']=3;
	
	mp.clear(); //清空map 
	printf("%d\n",mp.size());
	return 0;
}

输出:

 

4、map的常见用途

①需要建立字符(或字符串)与整数之间的映射的题目,使用map可以减少代码量。

②判断大整数或者其他类型数据是否存在的题目,可以把map当作bool数组来用。

③字符串和字符串的映射有时也可能会遇到。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值