原文链接:https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可以称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

1、map简介

map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。

对于迭代器来说,可以修改实值,而不能修改key。

2、map的功能

自动建立Key - value的对应。key 和 value可以是任意你需要的类型。

根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。

快速插入Key -Value 记录。

快速删除记录

根据Key 修改value记录。

遍历所有记录。

3、使用map

使用map得包含map类所在的头文件

#include <map>  //注意,STL头文件没有扩展名.h

map对象是模板类,需要关键字和存储对象两个模板参数:

std:map<int,string> personnel;

这样就定义了一个用int作为索引,并拥有相关联的指向string的指针.

为了使用方便,可以对模板类进行一下类型定义,

typedef map<int,CString> UDT_MAP_INT_CSTRING;

UDT_MAP_INT_CSTRING enumMap;

4、map的构造函数

map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:

map<int, string> mapStudent;

5、 数据的插入

在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:

#include<map>
#include<string>
#include<iostream>
using namespace std;
1.// 用insert插入pair数据
int main(){
map<int ,string> mapst;
mapst.insert(pair<int,string>(,"student1"));
mapst.insert(pair<int,string>(,"student2"));
mapst.insert(pair<int,string>(,"student3"));
map<int,string>::iterator it;
for(it=mapst.begin();it!=mapst.end();it++)
cout<<it->first<<" "<<it->second<<endl;
return ;
} 2.// 用insert函数插入value_type int main(){
map<int,string> mapst;
mapst.insert(map<int,string>::value_type(,"student1"));
mapst.insert(map<int,string>::value_type(,"student2"));
mapst.insert(map<int,string>::value_type(,"student3"));
map<int,string> ::iterator it;
for(it=mapst.begin();it!=mapst.end();it++)
cout<<it->first<<" "<<it->second<<endl;
} 3.// 用数组方式插入 int main(){
map<int,string> mapst;
mapst[]="student1";
mapst[]="student2";
mapst[]="student3";
map<int,string> ::iterator it;
for(it=mapst.begin();it!=mapst.end();it++)
cout<<it->first<<" "<<it->second<<endl;
}

以上三种用法,虽然都可以实现数据的插入,但是他们是有区别的,当然了第一种和第二种在效果上是一样的,用insert函数插入数据,在数据的插入上设计到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值,用程序说明:

mapst.insert(map<int,string>::value_type(,"student1"));
mapst.insert(map<int,string>::value_type(,"student2"));

上面这两条语句执行后,map中1这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下

pair<map<int, string>::iterator, bool> Insert_Pair;

Insert_Pair = mapStudent.insert(map<int, string>::value_type (1, "student_one"));

我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。

下面给出完成代码,演示插入成功与否问题:

#include<map>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
map<int,string> mapst;
pair<map<int ,string>::iterator,bool>insert_pair;
insert_pair=mapst.insert(map<int,string>::value_type(,"student1"));
if(insert_pair.second==true) cout<<"insert successfully"<<endl;
else cout<<"insert failure"<<endl;
insert_pair=mapst.insert(pair<int,string>(,"student2"));
if(insert_pair.second==true) cout<<"insert successfully"<<endl;
else cout<<"insert failure"<<endl;
map<int,string>::iterator it;
for(it=mapst.begin();it!=mapst.end();it++)
cout<<it->first<<" "<<it->second<<endl;
}

运行结果:

insert successfully
insert failure
1 student1

用数组插入在数据覆盖上的效果

#include<map>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
map<int,string> mapst;
mapst[]="student1";
mapst[]="student2";
mapst[]="student3";
map<int,string>::iterator it;
for(it=mapst.begin();it!=mapst.end();it++)
cout<<it->first<<" "<<it->second<<endl;
return ;
}

运行结果

1 student2
2 student3

6、map的大小

在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:

Int nSize = mapStudent.size();

7、     数据的遍历

这里也提供三种方法,对map进行遍历

第一种:应用前向迭代器,上面举例程序中到处都是了,略过不表

第二种:应用反相迭代器

#include<map>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
map<int,string> mapst;
mapst.insert(pair<int,string>(,"student1"));
mapst.insert(pair<int,string>(,"student2"));
mapst.insert(pair<int,string>(,"student3"));
map<int,string>::reverse_iterator it;
for(it=mapst.rbegin();it!=mapst.rend();it++)
cout<<it->first<<" "<<it->second<<endl;
return ;
}

运行结果:

3 student3
2 student2
1 student1

第三种,用数组的形式,程序说明:

#include<map>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
map<int,string> mapst;
mapst.insert(pair<int,string>(,"student1"));
mapst.insert(pair<int,string>(,"student2"));
mapst.insert(pair<int,string>(,"student3"));
int nsize=mapst.size();
//此处应注意,应该是 for(int i = 1; i <= nsize; i++)
//而不是 for(int i = 0; i < nsize; i++)
for(int i=;i<=nsize;i++)
cout<<mapst[i]<<endl;
return ;
}

运行结果:

student1
student2
student3

8、查找并获取map中的元素(包括判定这个关键字是否在map中出现)

在这里我们将体会,map在数据插入时保证有序的好处。

要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。

这里给出三种数据查找方法 :

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。

查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()和end()两个成员,

分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator.

程序说明:

#include<map>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
map<int,string> mapst;
mapst.insert(pair<int,string>(,"student1"));
mapst.insert(pair<int,string>(,"student2"));
mapst.insert(pair<int,string>(,"student3"));
int nsize=mapst.size();
map<int,string>::iterator it;
it=mapst.find();
if(it!=mapst.end())
cout<<"Find,the value is"<<it->second<<endl;
else cout<<"Do not Find"<<endl;
return ;
}

运行结果:

Find,the value is  student1

通过map对象的方法获取的iterator数据类型是一个std::pair对象,包括两个数据 iterator->first和 iterator->second分别代表关键字和存储的数据。

第三种:这个方法用来判定数据是否出现,

lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)

upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)

例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper_bound(2)的话,返回的就是3

Equal_range函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字。

#include<map>
#include<string>
#include<iostream>
using namespace std;
int main(){
map<int,string>mapst;
mapst[]="student1";
mapst[]="student3";
mapst[]="student5";
map<int,string>::iterator it;
it=mapst.lower_bound();
cout<<it->second<<endl;
it=mapst.lower_bound();
cout<<it->second<<endl;
it=mapst.lower_bound();
cout<<it->second<<endl;
it=mapst.upper_bound();
cout<<it->second<<endl;
it=mapst.upper_bound();
cout<<it->second<<endl;
pair<map<int, string>::iterator, map<int, string>::iterator> mappair;
mappair = mapst.equal_range();
if(mappair.first == mappair.second)
cout<<"Do not Find"<<endl;
else
cout<<"Find"<<endl;
mappair = mapst.equal_range();
if(mappair.first == mappair.second)
cout<<"Do not Find"<<endl;
else
cout<<"Find"<<endl;
return ;
}

运行结果:

student1
student3
student3
student3
student5
Do not Find
Find

9、    从map中删除元素

移除某个map中某个条目用erase()

该成员方法的定义如下:

iterator erase(iterator it);//通过一个条目对象删除

iterator erase(iterator first,iterator last)//删除一个范围

size_type erase(const Key&key);//通过关键字删除

clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());

这里要用到erase函数,它有三个重载了的函数,下面在例子中详细说明它们的用法:

#include<map>
#include<string>
#include<iostream>
using namespace std;
int main(){
map<int,string>mapst;
mapst.insert(pair<int, string>(, "student1"));
mapst.insert(pair<int, string>(, "student2"));
mapst.insert(pair<int, string>(, "student3"));
map<int,string>::iterator it;
it=mapst.find();
mapst.erase(it); //擦去容器1
// int n=mapst.erase(1); //如果删除了会返回1,否则返回0
// mapst.erase(mapst.begin(),mapst.end()); //用迭代器,成片的删除 一下代码把整个map清空
for(it=mapst.begin();it!=mapst.end();it++)
cout<<it->first<<" "<<it->second<<endl;
return ;
}

运行结果:

2 student2
3 student3

10.  map中的swap用法

map中的swap不是一个容器中的元素交换,而是两个容器所有元素的交换。

11.其他函数

map的基本操作函数:

C++ maps是一种关联式容器,包含“关键字/值”对

begin()         返回指向map头部的迭代器

clear()        删除所有元素

count()         返回指定元素出现的次数

empty()         如果map为空则返回true

end()           返回指向map末尾的迭代器

equal_range()   返回特殊条目的迭代器对

erase()         删除一个元素

find()          查找一个元素

get_allocator() 返回map的配置器

insert()        插入元素

key_comp()      返回比较元素key的函数

lower_bound()   返回键值>=给定元素的第一个位置

max_size()      返回可以容纳的最大元素个数

rbegin()        返回一个指向map尾部的逆向迭代器

rend()          返回一个指向map头部的逆向迭代器

size()          返回map中元素的个数

swap()           交换两个map

upper_bound()    返回键值>给定元素的第一个位置

value_comp()     返回比较元素value的函数

c++容器中map的应用的更多相关文章

  1. STL中map与hash_map容器的选择收藏

    这篇文章来自我今天碰到的一个问题,一个朋友问我使用map和hash_map的效率问题,虽然我也了解一些,但是我不敢直接告诉朋友,因为我怕我说错了,通过我查询一些帖子,我这里做一个总结!内容分别来自al ...

  2. 【转】C++中map容器的说明和使用技巧

    C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值. 一.map的说明    1   头文件   #include   <map> ...

  3. C++中map容器的说明和使用技巧

    C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值. 一.map的说明 1 头文件 #include <map> 2 定义 ma ...

  4. C++ STL 中 map 容器

    C++ STL 中 map 容器 Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它 ...

  5. 【Java心得总结七】Java容器下——Map

    我将容器类库自己平时编程及看书的感受总结成了三篇博文,前两篇分别是:[Java心得总结五]Java容器上——容器初探和[Java心得总结六]Java容器中——Collection,第一篇从宏观整体的角 ...

  6. 【Java心得总结六】Java容器中——Collection

    在[Java心得总结五]Java容器上——容器初探这篇博文中,我对Java容器类库从一个整体的偏向于宏观的角度初步认识了Java容器类库.而在这篇博文中,我想着重对容器类库中的Collection容器 ...

  7. JAVA的容器---List,Map,Set (转)

    JAVA的容器---List,Map,Set Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashM ...

  8. IOC容器中bean的生命周期

    一.Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务. Spring IOC容器对Bean的生命周期进行管理的过程如下: (1).通 ...

  9. C++中map的概念,与简单操作

     来源:http://blog.csdn.net/wallwind/article/details/6876892 C++map学习   map<Key, Data, Compare, Allo ...

随机推荐

  1. Objective-C 中的 Meta-class 是什么?

    在这篇文章中,我关注的是 Objective-C 中的一个陌生的概念-- meta-class.在 Objective-C 中的每个类都有一个相关联的 meta-class,但是你很少会直接使用 me ...

  2. 10 行 Python 代码实现模糊查询/智能提示

    10 行 Python 代码实现模糊查询/智能提示   1.导语: 模糊匹配可以算是现代编辑器(如 Eclipse 等各种 IDE)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的 ...

  3. android GPS: code should explicitly check to see if permission is available

    转载的,感谢作者,由于我找了很久才找到这个解决方法,因此我自己再转一遍 原文链接 https://blog.csdn.net/qinwendou/article/details/77849048 if ...

  4. SPSS分析:Bootstrap

    SPSS分析:Bootstrap 一.原理: 非参数统计中一种重要的估计统计量方差进而进行区间估计的统计方法,也称为自助法.其核心思想和基本步骤如下: 1.采用重抽样技术从原始样本中抽取一定数量(自己 ...

  5. Java基础:基本类型

    1.基本类型 Java中有8种基本类型,分为4类,分别为: 整型:包括  byte . short. int . long 泛型:float.double 字符型:char 布尔型:boolean 2 ...

  6. idea在同一窗口创建多个项目(详细步骤)

    需要创建的项目目录结构 1.file——>项目结构 2.创建一个新的模块

  7. 关于tomcat配置了虚拟路径,但是在Idea中无法生效的问题

    1. 确认 tomcat 的server.xml 文件中配置的虚拟路径是否正确 其中,path表示访问的虚拟路径,docBase表示真实路径 2. Idea 服务器配置中是否勾选 “Deploy ap ...

  8. 面试系列24 dubbo负载均衡策略和集群容错策略

    (1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...

  9. Amazon S3和EBS的区别

  10. JavaScript中对象的3种定义方式

    对象是有特性(属性)和功能(方法)的集合体. 定义对象有以下3种方式: 1.使用系统的new Object()方式定义对象 2.使用对象字面量定义对象( 即使用{}语法糖结构定义对象 ) 3.使用自定 ...