C++---STL标准库之map函数全解析,图文并茂,实例分析,迅速上手掌握!

map()的定义

map 翻译为映射,也是常用的STL容器。众所周知,在定义数组时(如 int array[100]),其实是定义了一个从 int 型到 int型的映射,比如 array[0]=25、array[4]=36就分别是将0映射到 25、将4映射到36。一个double 型数组则是将 int 型映射到 double 型。

例如 db[0]=3.14,db[1]=0.01。但是,无论是什么类型,它总是将 int 型映射到其他类型。这似乎表现出一个弊端∶当需要以其他类型作为关键字来做映射时,会显得不太方便。

例如有一本字典,上面提供了很多的字符串和对应的页码,如果要用数组来表示"字符串->页码"这样的对应关系,就会感觉不太好操作。这时,就可以用到 map,因为 map 可以将任何基本类型(包括 STL 容器)映射到任何基本类型(包括 STL 容器),也就可以建立string 型到 int 型的映射。

还可以来看一个情况;这次需要判断给定的一些数字在某个文件中是否出现过。按照正常的思路,可以开一个 bool 型 hashTable[max size],通过判断 hashTable[x]为 true 还是 false 来确定x是否在文件中出现。但是这会碰到一个问题,如果这些数字很大(例如有几千位),那么这个数组就会开不了。

而这时 map 就可以派上用场,因为可以把这些数字当成一些字符串,然后建立 string至 int 的映射(或是直接建立 int 至 int 的映射)。
如果要使用map,需要添加 map 头文件,即#include < map >。除此之外,还需要在头文件下面加上一句∶"using namespace std;",这样就可以在代码中使用map了。下面来看map 的一些常用用法。

单独定义一个map:

map<typename,typename> mp;

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

map<string,int> mp;

这是因为 char 数组作为数组,是不能被作为键值的。如果想用字符串做映射,必须用string。

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

map<set<int>,string> mp;

map容器内元素的访问

map 一般有两种访问方式∶通过下标访问或通过迭代器访问。下面分别讨论这两种访问方式。

(1)通过下标访问

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

#include<iostream>
#include<map>

using namespace std;

//map
int main()
{
	map<char,int> mp;
	mp['c'] = 20;
	mp['c'] = 30; // 20被覆盖 
	
	cout << mp['c'] << endl;
	
	return 0;
}

输出结果:

30

(2)通过迭代器访问

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

map<typenamel,typename2>::iterator it;

typename1和typename2就是定义 map 时填写的类型,这样就得到了迭代器it。map 迭代器的使用方式和其他 STL 容器的迭代器不同,因为 map 的每一对映射都有两个typename,这决定了必须能通过一个 it 来同时访问键和值。事实上,map可以使用 it->first 来访问键,使用 it->second 来访问值。

#include<iostream>
#include<map>

using namespace std;

//通过迭代器访问
//it -> first访问键
//it -> second访问值 
int main()
{
	map<char,int> mp;
	
	mp['m'] = 20;
	mp['r'] = 30;
	mp['a'] = 40;
	
	//it -> first 是当前映射的键
	//it -> second是当前映射的值 
	for(map<char,int>::iterator it = mp.begin(); it != mp.end(); it++)
	{
		cout << it -> first << " " << it -> second << endl;
	}
	
	return 0;
}

输出结果:

a 40
m 20
r 30

接下来似乎发现了一个很有意思的现象:map会以键从小到大的顺序自动排序,即按 a<m<r的顺序排列这三对映射。这是由于map 内部是使用红黑树实现的(set也是),在建立映射的过程中会自动实现从小到大的排序功能。

map常用函数

(1)find()

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

#include<iostream>
#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');
	
	cout << it -> first << " " << it -> second << endl;
	
	return 0;
}

输出结果:

b 2

(2)erase()

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

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

#include<iostream>
#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);
	
	for(map<char,int>::iterator it = mp.begin(); it != mp.end(); it++)
	{
		cout << it -> first << " " << it -> second << endl;
	}
	
	return 0;
}

输出结果:

a 1
c 3

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

#include<iostream>
#include<map>

using namespace std;

int main()
{
	map<char,int> mp;
	
	mp['a'] = 1;
	mp['b'] = 2;
	mp['c'] = 3;
	
	mp.erase('b'); //删除键为b的映射,即 b 2 
	
	for(map<char,int>::iterator it = mp.begin(); it != mp.end(); it++)
	{
		cout << it -> first << " " << it -> second << endl;
	}
	
	return 0;
}

输出结果:

a 1
c 3

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

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

#include<iostream>
#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++)
	{
		cout << it -> first << " " << it -> second << endl;
	}
	
	return 0;
}

(3)size()

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

#include<iostream>
#include<map>

using namespace std;

int main()
{
	map<char,int> mp;
	
	mp['a'] = 1;
	mp['b'] = 2;
	mp['c'] = 3;
	
	cout << mp.size() << endl; //3对映射 
	
	return 0;
}

输出结果:

3

(4)clear()

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

#include<iostream>
#include<map>

using namespace std;

int main()
{
	map<char,int> mp;
	
	mp['a'] = 1;
	mp['b'] = 2;
	mp['c'] = 3;
	
	mp.clear(); //清空map 
	
	cout << mp.size() << endl;
	
	return 0;
}

输出结果:

0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

livercy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值