当前位置: 首页 > news >正文

map暨例题

1.介绍:

        映射类似于函数的x和y的关系,每一个x对应一个y,而map是每一个键对应一个值。容器中每个存储对为一个键值对,包含两个元素(键和值)。

//头文件
#include<map>

1.1map初始化:

map<int,int>mp;
或map<string,string>mp;
或map<int,string>mp;
等等

map特点:map会按照键的顺序从小到大自动排序,键的类型可以比大小。

1.2常用的函数:

代码含义复杂度
mp.find(key)返回键为key的映射的迭代器O(logN)
mp.erase(it)删除迭代器对应的键和值O(logN)
mp.erase(first,last)删除左闭右开区间迭代器对应的键和值O(last−first)
mp.size()返回映射的对数O(1)
mp.clear()清空map中的所有元素O(N)
mp.insert()插入元素,插入时要构造键值对O(logN)
mp.empty()如果map为空,返回true,否则返回falseO(1)
mp.begin()返回指向map第一个元素的迭代器(地址)O(1)
mp.end()返回指向map尾部的迭代器(最后一个元素的下一个地址)O(1)
mp.rbegin()返回指向map最后一个元素的迭代器(地址)O(1)
mp.rend()返回指向map第一个元素前面(上一个)的逆向迭代器(地址)O(1)
mp.count(key)查看元素是否存在,因为map中键是唯一的,所以存在返回1,不存在返回0O(logN)
mp.lower_bound()返回一个迭代器,指向键>= key的第一个元素
mp.upper_bound()返回一个迭代器,指向键> key的第一个元素

1.3 迭代器进行正向遍历:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
#define int long long
signed main()
{
map<int,int> mp;
mp[3] = 4;
mp[5] = 6;
mp[7] = 8;
map<int,int>::iterator it = mp.begin();
while(it != mp.end()) {cout << it->first << " " << it->second << "\n";it ++;
}return 0;
}

1.4二分查找:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+5;
signed main()
{//lower_bound()//返回一个迭代器,指向键>=key的第一个元素 //upper_bound() //返回一个迭代器,指向键>key的第一个元素 map<int, int> m;m[3]=2,m[6]=2,m[2]=2,m[8]=5,m[9]=4;
//由于 map 会自动排序,最终 m 中的键值对顺序是
//	2: 2
//  3: 2
//  6: 2
//  8: 5
//	9: 4map<int, int>::iterator it1 = m.lower_bound(2);cout << it1->first << "\n";//it1->first=2map<int, int>::iterator it2 = m.upper_bound(2);cout << it2->first << "\n";//it2->first=3return 0;
}

 添加元素:

//先声明
map<string, string> mp;

 

方式一
mp["学习"] = "写作业";
mp["玩耍"] = "打go";

 

方式二:插入元素构造键值对

mp.insert(make_pair("vegetable","蔬菜"));
 

2.访问元素:

2.1下标访问 

mp["娃娃菜"] = "娃哈哈";
cout << mp["娃娃菜"] << "\n";//只是简写的一个例子,程序并不完整

 

2.2遍历访问:

迭代器访问:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+5;
signed main()
{
    map<string,string>mp;
    mp["小明"]="小红",mp["小美"]="小帅";
    map<string,string>::iterator it;
for(it = mp.begin(); it != mp.end(); it++) {
    //      键                 值 
    // it是结构体指针访问所以要用 -> 访问
    cout << it->first << " " << it->second << "\n";
    //*it是结构体变量 访问要用 . 访问
    //cout<<(*it).first<<" "<<(*it).second;
}
    return 0;
}

 3.例题

3.1题目链接:205. 同构字符串 - 力扣(LeetCode)

题目描述:

给定两个字符串 s 和 t ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

示例 1:

输入:s = "egg", t = "add"输出:true

示例 2:

输入:s = "foo", t = "bar"输出:false

示例 3:

输入:s = "paper", t = "title"输出:true

提示:

  • 1 <= s.length <= 5 * 10000
  • t.length == s.length
  • s 和 t 由任意有效的 ASCII 字符组成
 解题思路:

首先需要我们判断 s 和 t 每个位置上的字符是否都一一对应,即 s 的任意一个字符被 t 中唯一的字符对应,同时 t 的任意一个字符被 s 中唯一的字符对应。这也被称为「双射」的关系。

以示例 2 为例,t 中的字符 a 和 r 虽然有唯一的映射 o,但对于 s 中的字符 o 来说其存在两个映射 {a,r},故不满足条件。

因此,我们需要开两个哈希表,第一张哈希表以s中的字符串为键,映射至t中的字符串为值,第二张哈希表以t中的字符串为键,映射至s中的字符串为值。

从左往右遍历字符串,并不断更新哈希表,如果存在冲突(即当前下标对应的字符s[index]已经存在映射且不为t[inedex]或者t[index]不为s[inedex])时,说明两个字符无法构成同构,返回false,如果没有冲突返回true即可。

运行代码:
class Solution {
public:bool isIsomorphic(string s, string t) {unordered_map<char, char> s2t;unordered_map<char, char> t2s;int len = s.length();for (int i = 0; i < len; ++i) {char x = s[i], y = t[i];if ((s2t.count(x) && s2t[x] != y) || (t2s.count(y) && t2s[y] != x)) {return false;}s2t[x] = y;t2s[y] = x;}return true;}
};

3.2题目链接:完美K倍子数组 - 计蒜客

题目描述:

 解题思路:

1.若K是奇数,则只有这个新数组中全是K的倍数的数,才是完美的
2.若K是偶数,则除了新的数组全是K的倍数情况,还有一种是任意两个数的余数的和是K/2的倍数。
3.如果这个数组中没有K的倍数的数,则考虑两个数之和是K,而这种情况下,数组长度只能是2.

运行代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
#define int long long
signed main()
{int n,k,x;cin>>n>>k;map<int,int>mp;int bs=0,half=0,ff=0;
/*​​bs​​:记录数组中能被 k 整除的数的个数。这些数与其他任何数的和都能被 k 整除。
​​half​​:记录余数为 k/2 的数的个数。如果 k 是偶数,这些数两两之和能被 k 整除。
​​ff​​:如果存在两个数的余数互补(a%k + b%k = k),则标记为 1。*/for(int i=1; i<=n; i++) {cin >> x;if(x % k == 0)bs++;                         // 统计能被 k 整除的数的个数if(x % k == k/2)half++;                       // 统计余数为 k/2 的数的个数if(mp[k - x%k] == 0)           // 检查是否存在互补余数mp[x%k]++;elseff = 1;                    // 存在互补余数对
}if(k%2==1){half=0;                    //奇数 k 时,余数为 k/2 无意义}int an=max(half,bs);           // 取两种可能的最大值if(an>1) // 至少有 2 个数满足条件cout<<an;else if(ff)cout<<2; // 存在互补余数对,子数组长度为 2elsecout<<-1;return 0;
}

 3.3题目链接:叫号系统 - 计蒜客

题目描述:

有一家医院,病人到医院看病时,会先挂号排队,此时病人会获得一个唯一的编号 id。医院有一个病情评测机,它会自动根据病情给病人评测出病情的紧急程度 urg。一个病人到达医院后,会自动挂号、评测病情的紧急程度,并且会将信息加入到医院的叫号系统。叫号系统内保证所有排队的病人中所有的 id 和紧急程度 urg 均不相同。

 

样例输入1:

7

1 2 3

1 3 4

6 3

7 3

4 3 5

2

3

样例输出1:

4

2

2

3

运行代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
#define int long long  // 定义宏,将int替换为long long类型signed main() {int n, op, id, urg;map<int, int> a, b;  // 定义两个map容器:// a: id映射到urg(病人ID到紧急程度)// b: urg映射到id(紧急程度到病人ID)cin >> n;  // 输入操作总数while(n--) {  // 处理每个操作cin >> op;  // 输入操作类型// 操作1:添加病人if(op == 1) {cin >> id >> urg;  // 输入病人ID和紧急程度a[id] = urg;       // 建立id到urg的映射b[urg] = id;       // 建立urg到id的映射}// 操作2:叫号(选择紧急程度最小的病人)else if(op == 2) {if(b.size() == 0) {  // 如果没有病人cout << "error\n";} else {// 输出紧急程度最小的病人的ID(b.begin()是最小的urg)cout << b.begin()->second << '\n';// 删除该病人的记录a.erase(b.begin()->second);  // 从a中删除b.erase(b.begin());         // 从b中删除}}// 操作3:叫号(选择紧急程度最大的病人)else if(op == 3) {if(a.size() == 0) {  // 如果没有病人cout << "error\n";} else {// 输出紧急程度最大的病人的ID(--b.end()是最大的urg)cout << (--b.end())->second << '\n';// 删除该病人的记录a.erase((--b.end())->second);  // 从a中删除b.erase(--b.end());            // 从b中删除}}// 操作4:修改病人紧急程度else if(op == 4) {cin >> id >> urg;  // 输入病人ID和新的紧急程度b.erase(a[id]);    // 删除旧的urg到id映射a[id] = urg;       // 更新id到urg的映射b[urg] = id;       // 建立新的urg到id映射}// 操作5:修改病人IDelse if(op == 5) {cin >> id >> urg;  // 输入新的ID和紧急程度a.erase(b[urg]);    // 删除旧的id映射a[id] = urg;        // 建立新的id到urg映射b[urg] = id;        // 更新urg到id映射}// 操作6:根据ID查询紧急程度else if(op == 6) {cin >> id;  // 输入要查询的病人IDif(a.find(id) == a.end()) {  // 如果ID不存在cout << "error\n";} else {cout << a[id] << '\n';  // 输出对应的紧急程度}}// 操作7:根据紧急程度查询IDelse if(op == 7) {cin >> urg;  // 输入要查询的紧急程度if(b.find(urg) == b.end()) {  // 如果紧急程度不存在cout << "error\n";} else {cout << b[urg] << '\n';  // 输出对应的病人ID}}}return 0;
}

http://www.dtcms.com/a/275137.html

相关文章:

  • 卢比危机下的金融破局:科伦坡交易所技术升级作战图
  • C++类对象多态基础语法【超详细】
  • GTSuite许可服务器设置
  • 380. O(1) 时间插入、删除和获取随机元素
  • 深度学习:反向传播算法
  • Google Test 介绍和使用指南
  • 《QtPy:Python与Qt的完美桥梁》
  • STM32 IIC通信(寄存器与hal库实现)
  • 组件杠杠结构
  • 干眼症的预防与治疗
  • 域名锁是什么?有必要安装域名锁吗?
  • 拼数(字符串排序)
  • TransUnet医学图像分割模型
  • PrimeTime (PT Shell) report_timing 报告全字段完整解析
  • 深度对比扣子(Coze) vs n8n
  • halcon 求一个tuple的极值点
  • 上位机知识篇---高效下载安装方法
  • Auto-GPT 简易教程
  • Ant Design ProTable重置函数全解析
  • 【Ubuntu 22.04 ROS2 Humble】没有数字签名。 N: 无法安全地用该源进行更新
  • 47-RK3588 用瑞芯微官方提供recovery进行OTA升级
  • VR协作海外云:跨国企业沉浸式办公解决方案
  • ATAM与效用树:架构评估的核心方法论
  • 喷涂机器人cad【1张】+三维图+设计说明书+降重
  • 【SpringAI】6.向量检索(redis)
  • 【JAVA】面向对象三大特性之继承
  • PICO4 MR开发之外部存储读写
  • 论迹不论心
  • Vue和Element的使用
  • 【跟着PMP学习项目管理】每日一练 - 6