STL--map的应用

STL之map的应用

map定义及用途

map翻译为映射,是STL中的常用容器。
其实,数组就是一种映射,比如:int a[100];就是定义了一个int到int的映射。而a[5]=25;就是把5映射到25。数组总是将int类型映射到其它基本类型(称为数组的基类型),
这同时也带来了一个问题,有时候我们希望把string映射成一个int,数组就不方便了。这时就可以使用map,map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器)。
map 的用途至少有以下三种情形:

  1. 需要建立字符(串)与整数之间的映射,使用 map 可以减少代码量。
  2. 判断大整数(比如几千位)或者其他类型数据是否存在,可以把map当布尔型数组使用(哈希表)。
  3. 字符串与字符串之间的映射

在这里插入图片描述

map的使用

1、map的定义:
要使用map,必须先添加map头文件,即#include <map>,同时必须要有“using namespace std”。
定义一个map的方法为:

map<typename1,typename2> name;

其中,typename1是映射前的类型(键key),typename2是映射后的类型(值value),name为映射的名字。
1、普通int数组a就是map<int,int> a。
2、map的键和值也可以是STL容器,比如:map<set,string> mp。
3、map的键和值都是唯一的。

2、map的遍历

访问 map 的元素有两种方式,一种是通过下标访问;另一种是通过迭代器访问。
通过下标访问就像普通的数组元素访问,例如先定义map<char,int> mp,然后就可以通过mp[‘c’]的方式来访问它对应的元素,如mp[‘c’]=124。
通过迭代器访问,先作如下定义:

map<typename1,typename2>::iterator it;

因为map的每一对映射都有两个typename,所以,我们使用“it->first”来访问键,而使用“it->second”来访问值。
3、map插入

my_Map["a"]=1; // 最常用的方法
my_Map.insert(map<string,int>::value_type("b",2)); my_Map.insert(pair<string,int>("c",3)); my_Map.insert(make_pair<string,int>("d",4));

4、 map 的常用函数

(1)find()和 size()
find(key)是返回键为 key 的映射的迭代器,时间复杂度为 0(log2 n),n 为 map 中映射的对数。size()用来获得map中映射的对数,时间复杂度为O(1)。

(2)clear()
clear()用来清空 map,时间复杂度为 0(n)。
(3)erase()
erase()可以删除单个元素,也可以删除一个区间内的所有元素。
删除单个元素可以用:erase(it),it为要删除的元素的迭代器,时间复杂度为O(1)。
也可以用:erase(key),key为要删除的映射的键,时间复杂度为O(log2n)。
删除一个区间内的所有元素用:erase(first,last),first为区间的起始迭代器,last为区间的末尾迭代器的下一个地址,也就是左闭右开的区间[first,last),时间复杂度为O(last-first)。

pair 的定义和使用

pair 是“二元结构体”的替代品,将两个元素捆绑在一起,节省编码时间。相当于以下定义:

struct pair{
	typename1 first;
	typename2 second;
}

要使用pair,必须先添加头文件,即#include <utility>,同时,必须要有“using namespace std”。因为map的内部实现中涉及pair,因此添加map头文件时会自动添加utility头文件,此时可以省去utility头文件。
pair有两个参数,分别对应first和second的数据类型,可以是任意基本数据类型或者容器。
定义一个pair的方法为

pair<typename1,typename2> name;

map 和 pair 的应用举例

插入元素

// 定义一个map对象
map<int, string> mapStudent;
 
// 第一种 用insert函數插入pair
mapStudent.insert(pair<int, string>(000, "student_zero"));
 
// 第二种 用"array"方式插入
mapStudent[123] = "student_first";
mapStudent[456] = "student_second";

以上二种用法,虽然都可以实现数据的插入,但是它们是有区别的,用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是不能在插入数据的,但是用数组方式就不同了,它可以覆盖以前该关键字对 应的值,用程序说明如下:

mapStudent.insert(map<int, string>::value_type (001, "student_one"));
 
mapStudent.insert(map<int, string>::value_type (001, "student_two"));

上面这两条语句执行后,map中001这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下

// 构造定义,返回一个pair对象
pair<iterator,bool> insert (const value_type& val);
 
pair<map<int, string>::iterator, bool> Insert_Pair;
 
Insert_Pair = mapStudent.insert(map<int, string>::value_type (001, "student_one"));
 
if(!Insert_Pair.second)
    cout << ""Error insert new element" << endl;

查找元素

// find 返回迭代器指向当前查找元素的位置否则返回map::end()位置
iter = mapStudent.find("123");
 
if(iter != mapStudent.end())
       cout<<"Find, the value is"<<iter->second<<endl;
else
   cout<<"Do not Find"<<endl;

删除与清空map

//迭代器刪除
iter = mapStudent.find("123");
mapStudent.erase(iter);
 
//用关键字刪除
int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0
 
//用迭代器范围刪除 : 把整个map清空
mapStudent.erase(mapStudent.begin(), mapStudent.end());
//等同于mapStudent.clear()

map的大小

int nSize = mapStudent.size();

例题:最近的一对
[解题思路]
遍历数组的过程中,利用map 维护每个数字上一次出现的位置,这样可以快速计算每一个a j 所对应的ai 。过程中记录最近的一对出现的位置。

#include <bits/stdc++.h>
 using namespace std;
 int a[100005];
 int main() {
 map<int, int> pos;
 int n, min = 100005, minIndex = -1;

 cin >> n;
 for(int i = 0; i < n; i++)
 {
 cin >> a[i];

 if(pos.find(a[i]) != pos.end())
 {

 int pre = pos[a[i]];
 if(i - pre < min) {
 min = i - pre;
 minIndex = pre;
 }
 }
 pos[a[i]] = i;
 }
 if(minIndex == -1)
 cout << "No" << endl;
 else
 cout << a[minIndex] << endl;
 return 0;
}

练习题

1、求众数
2、A-B 数对
3、查字典

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

信奥教练Andy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值