map(终极奥义)

2024-04-23 21:08
文章标签 map 终极 奥义

本文主要是介绍map(终极奥义),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。数学上映射是一个值只能对应 另一个集合的唯一的一个值,不能有两个或以上,但是同一个 集合里面 会有 不同元素 对应另一个集合的 相同元素,这个 是可以允许的。

下面说说 map 基本用法:就用做复习吧

map 容器是默认递增序列的 ,如果想要改为递减的:map<int,int,greater<int>  >mp;   递增的也可以加 map<int,int,less<int>>mp; 就是 跟 那个 里面的 英文单词的意思相反。

1.MAP 数据的插入 有三种方法 :其中有两种与另外一种是不一样的,两种是 :如果map里面 已经有了 这个相同的元素,那就不会再插进去了;而第三种 则会 覆盖掉 他的映射。

第一和第二种:

using namespace std;
#include<map>
map<int,int,greater<int>>mp;
mp.insert(make_pair(5,5));
mp.insert(make_pair(100,1000));
#include<map>
map<int,int,greater<int>>mp;
mp.insert(pair<int,int>(10,10)); 
mp.insert(pair<int,int>(20,20));

第三种:其实很像数组 的赋值操作:

#include<map>
map<int,int,greater<int>>mp;
mp[1]=5;
mp[2]=100;
mp[0]=12;

第三种方法:其中中括号里面的 不是下标,而是一个key 值,后面的 值 是该值对应映射。

 2.map 元素的遍历,有正向遍历和逆向遍历 输出:

正向遍历:

for(auto it=mp.begin();it!=mp.end();it++)cout<<it->first<<' '<<it->second<<endl;cout<<endl;

逆向遍历:

 

cout<<"逆向遍历输出"<<endl;
for(auto it2=mp.rbegin();it2!=mp.rend();it2++)cout<<it2->first<<' '<<it2->second<<endl;cout<<endl;
it1=mp.begin();while(it1!=mp.end()){cout<<it1->first<<' '<<it1->second<<endl;it1++;}

 

这个是 数组形式输出,但是得要求第一个键值 得是 连续的。

#include<map>
map<int,int,less<int>>mp;
int main()
{int i;mp[1]=2;mp[2]=3;mp[3]=4;for(i=1;i<=mp.size();i++){cout<<mp[i]<<endl;}return 0;
}

也可这样输出,迭代器用过一次后,需要重新 返回 第一个元素 的迭代器。

3.数据的删除,查找(找到时返回该元素迭代器,否则返回尾部的迭代器),和判断元素是否存在count ,如存在返回1,不存在返回0。如下操作:

以下的搜索操作都是对 键 的查找 ,不是对 对应的值 的查找,这点容易弄错。

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
#include<map>
map<int,int,greater<int>>mp;
int main()
{//第一种插入 mp[1]=5;mp[2]=100;mp[0]=12;// 一个 迭代器可以重复使用 ,但需要 更新 mp.begin()  //正向迭代器 遍历输出 cout<<"正向遍历输出"<<endl;for(auto it=mp.begin();it!=mp.end();it++)cout<<it->first<<' '<<it->second<<endl;cout<<endl;//第二种插入 mp.insert(make_pair(5,5));mp.insert(make_pair(100,1000));//第三种插入mp.insert(pair<int,int>(10,10)); mp.insert(pair<int,int>(20,20));//逆向迭代器 遍历输出 cout<<"逆向遍历输出"<<endl;for(auto it2=mp.rbegin();it2!=mp.rend();it2++)cout<<it2->first<<' '<<it2->second<<endl;cout<<endl;map<int,int>::iterator it1=mp.begin();map<int,int>::iterator it5;//单个删除cout<<"单个删除"<<endl; it5=mp.find(100);mp.erase(it5);cout<<"删除后个数"<<endl;cout<<mp.size()<<endl;cout<<endl;cout<<"各元素值"<<endl;it1=mp.begin();while(it1!=mp.end()){cout<<it1->first<<' '<<it1->second<<endl;it1++;}cout<<endl;// 一连串 删除 cout<<"一长串删除"<<endl; it1=mp.begin(); mp.erase(it1++,mp.end());cout<<"删除后个数"<<endl;cout<<mp.size()<<endl;cout<<endl;cout<<"各元素值"<<endl;it1=mp.begin();if(mp.empty())cout<<"为空"<<endl; elsewhile(it1!=mp.end()){cout<<it1->first<<endl;it1++;}cout<<endl;mp[1]=5;mp[2]=100;mp[0]=12;cout<<"查找元素"<<endl;it1=mp.find(1);if(it1!=mp.end()){cout<<"找到了"<<endl; cout<<it1->first<<' '<<it1->second<<endl;}elsecout<<"没找到"<<endl;cout<<endl;		cout<<"查找次数"<<endl;cout<<mp.count(2)<<endl;cout<<mp.count(200)<<endl;return 0;
}

查找第一个大于或等于 要查的值 用 lower_bound 第一个 大于 该值 用 upper_bound   他们返回的都是 迭代器。在查之前需要先是递增序列 ,才可行的 。也是对 键的查找 ,不是对值 的查找。 

看看代码 实现 :

it1=mp.begin();it1=mp.lower_bound(2);if(it1->first==2)       //返回的是第一个大于或等于查找的元素的迭代器 {						//如果迭代器指的就是这个查找的值,那就找到了 cout<<"找到了"<<endl; cout<<it1->first<<' '<<it1->second<<endl;}else                    //否则就没有找到 cout<<"没找到"<<endl;

这个 跟那个 it1=find(x) ,还是有点区别的,如果找到 it1,it1迭代器指的就不是 尾部元素的 迭代器。如果指的是最后一个元素的迭代器 ,那就是没有找到。

代码实现:

it1=mp.find(1000);if(it1!=mp.end())   //这个是跟 末尾迭代器 比的                      {					 cout<<"找到了"<<endl; cout<<it1->first<<' '<<it1->second<<endl;}elsecout<<"没找到"<<endl; 

 

重要的 知识点

1.map 既然是映射,就可以根据左键值,找到右值,可以说是一种搜索吧(但是有的题目数据量大,用map搜会超时,这时就可以用数组来替代 map ) ,在一些 数据搜索时 ,就会用到这个 方法(信息与信息之间的匹配)。

当然这里的 map<  a ,b  > a和b的数据类型  可以是 int ,int  ;            string,int ;           string,string;         int ,string;等等 。

2.map 其实就是一个一个 的 键值对,键 不能重复 ,而值 可以重复,就像函数 一个自变量,不能 有两个或多个 y值于x对应,比如 1对应 2,2 对应 2,但是 1就不能对应 其他的 值了。

3.用map 来匹配信息 ,用 第三种方法来插入信息,mp[xx]=yy;  这样信息xx 与 信息 yy 之间 建立了某种关系 ,就可以 直接 mp[xx]  来找到这个yy ,但是 不能反过来寻找 。    

下面就是一些map 的排序相关的知识:

https://blog.csdn.net/chengqiuming/article/details/89816566  这个是一些大神的博客,写的很清楚

key值为结构体的时候,我们可以使用以下的方法    struct node{string name;int score;node(string name1,int now){name=name1,score=now;}bool operator<(const node& a)const{if(score!=a.score)return score>a.score;return name<a.name;}}; typedef pair<node,int> p;map<node,int>s;如果是只对key的某一个元素进行排序的话,我们直接写一个cmp 出来就可以了。map<string,int,cmp>s;struct cmp{//是对key 进行排序,如果对value的话,会出错的 bool operator()(const string& a,const string& b){return a>b;   //也是不等式号指向哪,哪就大  }};

下面我们对value/key进行 排序,我们借助其他容器来实现操作:(根据自定义函数,我们可以写出排序规则)

#include<iostream>
#include<bits/stdc++.h>using namespace std;
typedef pair<int,int> p;bool cmp(p a,p b)
{if(a.second!=b.second)return a.second>b.second;elsereturn a.first<b.first;
}int main()
{//对value 进行排序,借助 vector map<int,int>mp;mp[1]=3;mp[5]=1;mp[999]=111;mp[12]=111;vector<p>s(mp.begin(),mp.end());sort(s.begin(),s.end(),cmp);for(int i=0;i<s.size();i++)cout<<s[i].first<<' '<<s[i].second<<endl;return 0;
}

 当出现两个map 一起用的时候(有时是双对应的才可以解决问题),所以我们采用map 套用map,方法有些不一样:

#include<iostream>
#include<map>
#include<vector>
#include<algorithm>using namespace std;
typedef pair<int, int> p;int main()
{map<int, map<int, int>>s;s[1][2] = 3;s[2][2] = 15;for (auto it1 = s.begin(); it1 != s.end(); it1++){cout << it1->first << ' ';map<int, int>s2 = it1->second;for (auto it2 = s2.begin(); it2 != s2.end(); it2++)cout << it2->first << ' ' << it2->second << endl;}return 0;
}

这样可以 装下3个元素的对应关系,我们就可以解决问题了。
 

这篇关于map(终极奥义)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/929885

相关文章

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

Map

Map 是 Java 中用于存储键值对的集合接口。以下是对 Map 的详细介绍: 特点 键值对存储:每个元素包含一个键和一个值。 键唯一:键不能重复,但值可以重复。 无序/有序:根据具体实现,键值对的顺序可能无序(如 HashMap)或有序(如 TreeMap、LinkedHashMap)。 主要实现类 HashMap 基于哈希表,无序存储。 允许一个 null 键和多个 null 值。

Java中集合类Set、List和Map的区别

Java中的集合包括三大类,它们是Set、List和Map,它们都处于java.util包中,Set、List和Map都是接口,它们有各自的实现类。Set的实现类主要有HashSet和TreeSet,List的实现类主要有ArrayList,Map的实现类主要有HashMap和TreeMap。那么它们有什么区别呢? Set中的对象不按特定方式排序,并且没有重复对象。但它的有些实现类能对集合中的对

C++数据结构重要知识点(5)(哈希表、unordered_map和unordered_set封装)

1.哈希思想和哈希表 (1)哈希思想和哈希表的区别 哈希(散列、hash)是一种映射思想,本质上是值和值建立映射关系,key-value就使用了这种思想。哈希表(散列表,数据结构),主要功能是值和存储位置建立映射关系,它通过key-value模型中的key来定位数组的下标,将value存进该位置。 哈希思想和哈希表数据结构这两个概念要分清,哈希是哈希表的核心思想。 (2)unordered

【C++STL(十四)】一个哈希桶简单模拟实现unordered_map/set

目录 前言 一、改造哈希桶 改造结点类 改造主体  模板参数改造  迭代器(重点) 改造完整哈希桶 unordered_map模拟实现 unordered_set模拟实现 前言 前面的文章都有说unordered_map/set的底层结构就是哈希表,严格来说是哈希桶,那么接下来我们就尝试使用同一个哈希桶来模拟实现一下。整体的逻辑和一棵红黑树封装map/set类似,所以

Java中Map取值转String Null值处理

Map<String, Object> 直接取值转String String value = (String)map.get("key") 当map.get(“key”)为Null值时会报错。 使用String类的valueOf静态方法可以解决这个问题 String value = String.valueOf(map.get("key"))

Creating OpenAI Gym Environment from Map Data

题意:从地图数据创建 OpenAI Gym 环境 问题背景: I am just starting out with reinforcement learning and trying to create a custom environment with OpenAI gym. However, I am stumped with trying to create an enviro

【Java编程的逻辑】Map和Set

HashMap Map有键和值的概念。一个键映射到一个值,Map按照键存储和访问值,键不能重复。 HashMap实现了Map接口。 基本原理 HashMap的基本实现原理:内部有一个哈希表,即数组table,每个元素table[i]指向一个单向链表,根据键存取值,用键算出hash值,取模得到数组中的索引位置index,然后操作table[index]指向的单向链表。 存取的时候依据键的

RDD的map和flatMap

在 Apache Spark 中,map 和 flatMap 是 RDD(弹性分布式数据集)中最常用的转换操作之一。 map 假设你有一个包含整数的 RDD,你想要计算每个元素的平方。 from pyspark import SparkContextsc = SparkContext(appName="MapExample")# 创建一个包含整数的 RDDnumbers = sc.para

【python 多进程传参】pool.map() 函数传多参数

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。人工智能教程 一、背景介绍 相信很多人都用过,pool.map()函数,这个函数,有两个参数可以传,第一个参数传的是函数,第二个参数传的是数据列表。 那么怎么在第二个数据列表,多传几个参数呢,方法是通过对有多个参数的方法进行封装