====C++map(映射)的常用用法
前提:头文件#include
1.map 的定义
(1)普通定义map
map< type1, type2 > mp ;
(2)嵌套定义map
map套set(一对多,自动去重)
// 一个key对应一堆不重复元素map<string, set<string>> ms;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 222b 333c 444
输入 输出
mp['c'] = 222; a 333mp['a'] = 333; b 444mp['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 222c 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 222c 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;}