====C++map(映射)的常用用法

====C++map(映射)的常用用法

====C++map(映射)的常用用法

前提:头文件#include

1.map 的定义

(1)普通定义map

map< type1, type2 > mp ;

(2)嵌套定义map

  1. map套set(一对多,自动去重)

    // 一个key对应一堆不重复元素

    map<string, set<string>> ms;

  2. map套map(二位映射)

    // 二维键值,像二维数组

    map<int, map<int, int>> mm;

map < string, int > mp;

map的键和值也可以是STL容器

type1 键类型:必须是支持比较<> string ,int, set, vector,自定义结构体

type2 值类型

map<set<int>, string> mp;

特点

注!!!

1.键唯一,不能重复!重复会覆盖!

2.自动按键从小到大排序

3.底层:红黑树

map内部是由红黑树实现的(set也是),在建立映射的过程中,会自动实现从小到大排序功能。

4.如果是字符串类型到整型的映射,必须是string而不能是char数组(不能作为键值)

5.访问不存在的键会自动创建 所以使用前一定要判断 if ( mp.count (x) )

map<char, int> mp;` `mp['c'] = 20;` `mp['c'] = 30; //30覆盖了20` `mp['c'] = 666; //666覆盖了30` `cout << mp['c']; //答案输出666

2、map容器内元素的访问

两种访问方式:通过下标访问或通过迭代器访问

(1)通过下标访问:

和普通数组一样

mp['a'] = 100;

cout << mp['a'];

(2)通过迭代器访问:

map < 键类型 , 值类型 > :: iterator 迭代器名;

it->first来访问键

it->second来访问值

for(auto it = mp.begin(); it != mp.end(); it++)

{

cout << it->first << " " << it->second << endl;

}

代码:

#include<iostream>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['a'] = 222;
mp['b'] = 333;
mp['c'] = 444;
for(map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
cout << it->first;
cout << " ";
cout << it->second;
cout << endl;
}
return 0;
}

输出结果

a 222
b 333
c 444

输入 输出

mp['c'] = 222; a 333
mp['a'] = 333; b 444
mp['b'] = 444; c 222

3、map常用函数

(1)mp.find(key)

auto it = mp.find('a');

#include<iostream>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['a'] = 222;
mp['b'] = 333;
mp['c'] = 444;
map<char, int>::iterator it = mp.find('b');
cout << it->first << " " << it->second;
return 0;
}

(2)mp.erase()

① 删除单个元素:

*mp.erase(it)*it为需要删除的元素的迭代器

#include<iostream>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['a'] = 222;
mp['b'] = 333;
mp['c'] = 444;
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 222
c 444

mp.erase(key),key为要删除的映射的键

#include<iostream>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['a'] = 222;
mp['b'] = 333;
mp['c'] = 444;
//map<char, int>::iterator it = mp.find('b');
//mp.erase(it);
mp.erase('b');
for(map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
cout << it->first << " " << it->second << endl;
}
return 0;
}

输出

a 222
c 444

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

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

#include<iostream>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['a'] = 222;
mp['b'] = 333;
mp['c'] = 444;
map<char, int>::iterator it = mp.find('b');
mp.erase(it, mp.end()); //删除it之后的所有映射,即b 333和 c 444
//mp.erase(it);
//mp.erase('b');
for(map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
cout << it->first << " " << it->second << endl;
}
return 0;
}

(3)mp.size()

返回键值对数量

(4)mp.count(key)

判断key是否存在

存在返回1 不存在返回0

(5)mp.clear()

清空map

嵌套例题

//B万年沉睡的宝藏
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
// 输入输出加速
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

ll q; // 总操作次数
ll op; // 操作编号
string x,y;

int main()
{
IOS; // 开启快读快写,防止超时

cin>>q;
// map:岛屿名 -> 该岛屿拥有的宝藏集合
// set 自动去重,同一个宝藏不会重复统计
map<string ,set<string>>bao;

while(q--)
{
cin>>op;

// 操作1:给岛屿 x 新增一个宝藏 y
if(op==1)
{
cin>>x>>y;
bao[x].insert(y); // 往岛屿x的宝藏集合里加入宝藏y
}

// 操作2:查询岛屿 x 有多少个不同宝藏
if(op==2)
{
cin>>x;
// 如果岛屿不存在,输出0;否则输出宝藏个数
if(!bao.count(x))
{
cout<<0<<endl;
}
else
{
cout<<bao[x].size()<<endl;
}
}

// 操作3:查询岛屿 x 是否拥有宝藏 y
if(op==3)
{
cin>>x>>y;
// 岛屿都不存在,直接输出0
if(!bao.count(x))
{
cout<<0<<endl;
}
else
{
// set.count 有就返回1,没有返回0
cout<<bao[x].count(y)<<endl;
}
}

// 操作4:查询一共有多少个出现过的岛屿
if(op==4)
{
// map.size() 就是岛屿总数
cout<<bao.size()<<endl;
}
}

return 0;
}