C++中的map翻译为映射,不是地图!!! 也是常用的STL容器。它在算法竞赛中应用十分广泛,因为map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器),十分灵活。因此我们很有必要来熟练map的常用用法。
目录
单独定义一个map:
map<typename1, typename2> mp;
其中,typename1是键的类型,typename2是值的类型。
注:如果是字符串到整型的映射,必须使用string而不能用char数组!
map<string, int> mp;
这是因为char数组作为数组,是不能被作为键值的。所以如果想用字符串做映射,必须用string。
再举个栗子例子:map的键和值也可以是STL容器,例如以下代码将一个set容器映射到一个字符串:
map<set<int>, string> mp;
一般有两种访问方式:通过下标访问或通过迭代器访问:
1、通过下标访问:
和普通数组一样,例如一个定义为map<char, int> mp的map来说,可以直接使用mp['c']的方式来访问它对应的int整数。可以直接使用mp['c'] = 20这样的方式来赋值:
map<char, int> mp;
mp['c'] = 20;
cout << mp['c']; //答案输出20
但是要注意的是,map中的键是唯一的,例如以下代码:
map<char, int> mp;
mp['c'] = 20;
mp['c'] = 30; //30覆盖了20
mp['c'] = 666; //666覆盖了30
cout << mp['c']; //答案输出666
2、通过迭代器访问:
map迭代器的定义和其他STL容器迭代器定义的方式相同:
map<typename1, typename2>::iterator it;
这样就得到了迭代器 it 。
map可以使用it->first来访问键,it->second来访问值:
#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
还有一点要补充,就是map会以键从小到大的顺序自动排序,如:
mp['c'] = 222;
mp['a'] = 333;
mp['b'] = 444;
顺序输出结果是(即按a < b < c的顺序从小到大排序):
a 333
b 444
c 222
上述现象是因为,map内部是由红黑树实现的(set也是),在建立映射的过程中,会自动实现从小到大排序功能。
find(key)返回键为key映射的迭代器,时间复杂度为O(logN),N为map中映射的个数:
#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;
}
输出结果:
b 333
erase()有两种用法:1、删除单个元素。2、删除一个区间内所有的元素。
① 删除单个元素:
mp.erase(it),it为需要删除的元素的迭代器。时间复杂度为O(1):
#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为要删除的映射的键。时间复杂度O(logN),N为map内元素的个数:
#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)。时间复杂度为O(last - first):
#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;
}
输出结果:
a 222
size()用来获得map中映射的对数,复杂度为O(1)。
#include<iostream>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['a'] = 222;
mp['b'] = 333;
mp['c'] = 444;
cout << mp.size();
return 0;
}
输出结果:
3
clear()用来清空map中的所有元素,复杂度为O(N),N为map中元素个数:
#include<iostream>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['a'] = 222;
mp['b'] = 333;
mp['c'] = 444;
mp.clear(); //清空map
cout << mp.size();
return 0;
}
输出结果:
0
map的键和值是唯一的,如果需要一个键对应多个值,就只能用multimap。另外,C++11标准新增了unordered_map,以散列代替map内部的红黑树实现,使其可以用来处理只映射而不按key排序的需求,速度比map要快得多。
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法
我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有
Enumerable#each和Enumerable#map的区别在于返回的是接收者还是映射后的结果。回到接收者是微不足道的,你通常不需要在each之后继续一个方法链,比如each{...}.another_method(我可能没见过这样的案例。即使你想回到接收者那里,你也可以通过tap来实现)。所以我认为所有或者大部分使用Enumerable#each的情况都可以用Enumerable#map代替。我错了吗?如果我是对的,each的目的是什么?map是否比each慢?编辑:我知道当您对返回值不感兴趣时使用each是一种常见的做法。我对这种做法是否存在不感兴趣,但感兴趣的是,除了从
我在尝试使用Faraday将文件上传到网络服务时遇到问题。我的代码:conn=Faraday.new('http://myapi')do|f|f.request:multipartendpayload={:file=>Faraday::UploadIO.new('...','image/jpeg')}conn.post('/',payload)尝试发布后似乎没有任何反应。当我检查响应时this是我所看到的:#:post,:body=>#,#,@opts={}>,#],@index=0>>,#>],@ios=[#,#,@opts={}>,#],@index=0>,#],@index=0>
我使用raise(ConfigurationError.new(msg))引发错误我试着用rspec测试一下:expect{Base.configuration.username}.toraise_error(ConfigurationError,message)但这行不通。我该如何测试呢?目标是匹配message。 最佳答案 您可以使用正则表达式匹配错误消息:it{expect{Foo.bar}.toraise_error(NoMethodError,/private/)}这将检查NoMethodError是否由privateme
电脑上可以截取图片吗?如果可以,该如何操作呢?相信很多小伙伴都只知道一两种截图的方式,知道的并不全面。其实,电脑上有多种方式截图的,而且非常方便。电脑怎么截图?今天我们就来教大家如何使用电脑截取图片的8种常用方式!操作环境:演示机型:Delloptiplex7050系统版本:Windows10方法一:系统自带截图具体操作:同时按下电脑的自带截图键【Windows+shift+S】,可以选择其中一种方式来截取图片:截屏有矩形截屏、任意形状截屏、窗口截屏和全屏截图。 方法二:QQ截图具体操作:在电脑登录QQ,然后同时按下【Ctrl+Alt+A】,可以任意截图你需要的界面,可以把截图的页面直接下载,
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
map遍历数组是否比each更快?两者有速度差异吗?mapresult=arr.map{|a|a+2}每个result=[]arr.eachdo|a|result.push(a+2)end 最佳答案 我认为是的。我试过这个测试require"benchmark"n=10000arr=Array.new(10000,1)Benchmark.bmdo|x|#Mapx.reportdon.timesdoresult=arr.map{|a|a+2}endend#Eachx.reportdon.timesdoresult=[]arr.each