MAP —— 映射入门
map
中的元素分为两个部分:
- 关键字(
key
)。每个关键字只能出现一次。 - 值(
val
)
即键值对。
在map
中,元素按照关键字进行排序,因此,我们不能直接修改map
容器中的关键字,且map
中不允许多个元素的关键字相同。(相比之下,在multimap
中,可以出现多个相同的键)
MAP的作用:顾名思义,map
的作用是将一种类型的数据映射为另一种类型的数据。如:
map<string,int> m1;
可以将string
映射成int
map<double,int> m2;
可以将double
映射成int
map
的作用类似于pair
:pair
是将两个数据合成为一组数据,可以将其理解为特殊的结构体。
pair的初始化及输出
pair<t1,t2> p1;
—— 初始化一个空的pair
pair<t1,t2> p1(v1,v2);
—— 初始化之后赋值make_pair(v1,v2)
—— 使用函数初始化
#include <iostream>
using namespace std;
typedef pair<int,string> PII;
int main()
{
PII p1 = {1,"yangyu"};
PII p2 = {2,"xiaochu"};
PII p3 = {3,"wangwei"};
cout << p1.first << " " << p1.second << endl;//访问pair的成员变量
cout << p2.first << " " << p2.second << endl;
cout << p3.first << " " << p3.second << endl;
}
MAP集合中的一些函数
find(关键字)
—— 返回关键字映射到对应元素的位置的迭代器。如果没有这个关键字,则返回map.end()
count(关键字)
—— 由于map
中的关键字互不相同,故要么关键字存在,返回1;要么关键字不存在,返回0insert()
—— 插入一个键值对erase()
—— 删除的是指定位置或者指定关键字的值clear()
—— 清空容器begin()
—— 返回map
集合中第一个元素对应位置的迭代器end()
—— 返回容器最后一个元素后面的那个位置size()
—— 返回集合中元素的个数empty()
—— 判断集合是否为空(等价于map.size() == 0
)
MAP的一些基本操作
map
集合中的元素默认按照关键字从小到大升序排列,即默认使用less
比较器,换句话说,以下两种写法等价:
map<int,string> m;
map<int,string,less<int> > m;
如果想让map
集合中的元素按照关键字从大到小降序排列,则应该使用greater
比较器,写法如下:
map<int,string,greater<int> > m;
#include <iostream>
#include <cstring>
#include <string>
#include <map>
using namespace std;
int main()
{
map<int,string,greater<int> > m;//降序排列的映射
m[1] = "chu";
m[2] = "zhou";
m[3] = "yang";
pair<int,string> p = {4,"he"};
m.insert(p);//插入函数
/*
m.erase(3);//删除键为3所对应的值
m.erase(m.begin());//删除首位元素
*/
//遍历map
map<int,string>::iterator it;
for (it = m.begin();it != m.end();it++)
{
cout << it->first << " " << it->second;
cout << endl;
}
return 0;
}
例题(原题链接)
题目描述
输入n个不同的坐标,按x轴的值从小到大排序,如果x相同,则按照y排序。
输入
第1行是一个整数n(n<=10000)。 接下来有n行,每行有2个整数,代表了1个点的坐标。
输出
输出n行,每行有2个整数,输出排序后的n个坐标。
样例输入
4
-1 -1
1 1
-1 1
1 -1
样例输出
-1 -1
-1 1
1 -1
1 1
解题思路:可以直接使用结构体存储数据
AC代码1:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
struct node
{
int x;
int y;
}a[N];//结构体类型的数组
bool cmp(node a,node b)
{
return (a.x < b.x) || (a.x == b.x && a.y < b.y);
}
int main()
{
int n; cin >> n;
for (int i = 1;i <= n;i++) cin >> a[i].x >> a[i].y;
sort(a + 1,a + 1 + n,cmp);
for (int i = 1;i <= n;i++) cout << a[i].x << " " << a[i].y << endl;
return 0;
}
例2(原题链接)
题目描述
小X很关心自己在学校的表现。
班主任手上有一本“个人得分记录本”,如果一位同学表现好就会加分,表现差则会扣分。学期结束,每位同学都得知了自己的个人得分。小X想知道其他同学情况如何,但由于排名不公布,他只好一个个去问班里的其他同学。
现在,小X手上有班里共N位同学的个人得分,他想知道每位同学的排名 (得分相同则排名相同,见样例),可并不知道该如何计算,希望你帮帮他。
输入
第一行包含一个整数N。 接下来N行,第i行包含一个整数Ai,表示第i位同学的得分。
输出
N行,第i行包含一个整数,表示第i位同学的排名。
样例输入
5
95
100
99
99
96
样例输出
5
1
2
2
4
提示
数据范围 对于30%的数据,N≤10。 对于60%的数据,N≤1000。 对于
100%的数据,1≤N≤100000,0≤Ai≤100000。
解题思路:分析题意可知,每个分数的排名是唯一的,即一个值对应唯一的一个键,故使用map
解题即可。
AC代码: