STL之map和multimap容器

1.简介

  • map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对。它提供基于key的快速检索能力。
  • map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
  • map的具体实现采用红黑树变体的平衡二叉树的数据结构。在插入操作和删除操作上比vector快。
  • map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。
  • multimap与map的区别:map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符。
#include <map>

2.对象的拷贝构造和赋值

map/multimap采用模板类实现,对象的默认构造形式:

map<T1,T2> mapTT;
multimap<T1,T2> multimapTT; 

如:

map<int, char> mapA;
map<string,float> mapB;
//其中T1,T2还可以用各种指针类型或自定义类型

3.插入与迭代器

map.insert(...);    //往容器插入元素,返回pair<iterator,bool>

在map中插入元素的三种方式:
假设map<int, string> mapStu;
一、通过pair的方式插入对象

mapStu.insert( pair<int,string>(3,"小张") );

二、通过make_pair的方式插入对象

mapStu.inset(make_pair(-1, “校长-1”));

三、通过value_type的方式插入对象

mapStu.insert( map<int,string>::value_type(1,"小李") );

四、通过数组的方式插入值

mapStu[3] = “小刘";
mapStu[5] = “小王";

前三种方法,采用的是insert()方法,该方法返回值为pair<iterator,bool>
第四种方法非常直观,但存在一个性能的问题。插入3时,先在mapStu中查找主键为3的项,若没发现,则将一个键为3,值为初始化值的对组插入到mapStu中,然后再将值修改成“小刘”。若发现已存在3这个键,则修改这个键对应的value。

注意:string strName = mapStu[2]; //取操作或插入操作
只有当mapStu存在2这个键时才是正确的取操作,否则会自动插入一个实例,键为2,值为初始化值。

假设 map<int, string> mapA;

#include <iostream>
#include <map>
#include <string>using namespace std;// 遍历
void printA(map<int, string> &m)
{map<int, string>::iterator it = m.begin();while (it != m.end()){cout << it->first << '\t' << it->second << endl;it++;}
}void printA(map<string, int> &m)
{map<string, int>::iterator it = m.begin();while (it != m.end()){cout << it->first << '\t' << it->second << endl;it++;}
}// map 插入 删除 遍历
void func1()
{// map 里存的是键值对// 这里定义一个map  它的键是 int 类型, 值是string 类型map<int, string> m;// 1、通过构建 pair 对组进行数据插入m.insert (pair<int, string>(3, "小赵"));m.insert (pair<int, string>(2, "小钱"));// 2、通过make_pair 来构建数据m.insert(make_pair(8, "小孙"));m.insert(make_pair(4, "小李"));// 3、通过 map 的值类型插入数据m.insert(map<int, string>::value_type(5, "小周"));m.insert(map<int, string>::value_type(6, "小吴"));// 4、通过 [] 来写入数据// [] 和数据下标不是一回事情,里面放的不是数组下标,是map的 键m[13] = "小郑";m[11] = "小王";// 遍历
//  printA(m);// map 内部元素是通过 键进行排序,排序方式和 set 是一样,也可以自己指定排序方式map<int, string, greater<int>> m1;// 删除m.erase(5);  // 通过键 直接删除对应元素// printA(m);// 通过迭代器删除m.erase(m.begin());printA(m);
}// 打印 map 的插入操作是否成功
void printA(pair<map<string, int>::iterator, bool> &ret)
{map<string, int>::iterator it = ret.first;if (ret.second)cout << "插入成功,插入的元素是: " << it->first << '\t' << it->second <<  endl;elsecout << "插入失败" << endl;
}// 插入方式的比较
void func2()
{// 键可以是任意类型// 键是 string 类型, 值是 int 类型map<string, int> m;m.insert(pair<string, int>("小赵", 20));m.insert(make_pair("小张", 12));m.insert(map<string, int>::value_type("小王", 23));m["小钱"] = 12;// 前三种 可以通过返回值对插入操作进行判断是否成功pair<map<string, int>::iterator, bool> ret = m.insert(pair<string, int>("小孙", 20));printA(ret);ret = m.insert(make_pair("小李", 12));printA(ret);ret = m.insert(map<string, int>::value_type("小李", 23));printA(ret);m["小周"] = 15;// 通过 [] 操作map数据 如果数据不存在,会建一个新的键值对// 如果键存在,会用新的值替换原有的键值m["小李"] = 90;printA(m);
}

less与greater 可以替换成其它的函数对象functor。

可编写自定义函数对象以进行自定义类型的比较,使用方法与set构造时所用的函数对象一样。

map.begin();  //返回容器中第一个数据的迭代器。
map.end();  //返回容器中最后一个数据之后的迭代器。
map.rbegin();  //返回容器中倒数第一个元素的迭代器。
map.rend();   //返回容器中倒数最后一个元素的后面的迭代器。

3.对象的拷贝构造和赋值

map(const map &mp);          //拷贝构造函数
map& operator=(const map &mp);  //重载等号操作符
map.swap(mp);               //交换两个集合容器

例如:

map<int, string> mapA;
mapA.insert(pair<int,string>(3,"小张"));  
mapA.insert(pair<int,string>(1,"小杨"));  
mapA.insert(pair<int,string>(7,"小赵"));  
mapA.insert(pair<int,string>(5,"小王"));  map<int ,string> mapB(mapA);            //拷贝构造map<int, string> mapC;
mapC = mapA;                                //赋值mapC[3] = "老张";
mapC.swap(mapA);            //交换

4.大小

map.size(); //返回容器中元素的数目
map.empty();//判断容器是否为空
map<int, string> mapA;
mapA.insert(pair<int,string>(3,"小张"));  
mapA.insert(pair<int,string>(1,"小杨"));  
mapA.insert(pair<int,string>(7,"小赵"));  
mapA.insert(pair<int,string>(5,"小王"));  if (mapA.empty())
{int iSize = mapA.size();        //iSize == 4
}

5.删除

map.clear();        //删除所有元素
map.erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
map.erase(beg,end);     //删除区间[beg,end)的所有元素    ,返回下一个元素的迭代器。
map.erase(keyElem);     //删除容器中key为keyElem的对组。
map<int, string> mapA;
mapA.insert(pair<int,string>(3,"小张"));  
mapA.insert(pair<int,string>(1,"小杨"));  
mapA.insert(pair<int,string>(7,"小赵"));  
mapA.insert(pair<int,string>(5,"小王"));  //删除区间内的元素
map<int,string>::iterator itBegin=mapA.begin();
++ itBegin;
++ itBegin;
map<int,string>::iterator itEnd=mapA.end();
mapA.erase(itBegin,itEnd);          //此时容器mapA包含按顺序的{1,"小杨"}{3,"小张"}两个元素。mapA.insert(pair<int,string>(7,"小赵"));  
mapA.insert(pair<int,string>(5,"小王"));  //删除容器中第一个元素
mapA.erase(mapA.begin());       //此时容器mapA包含了按顺序的{3,"小张"}{5,"小王"}{7,"小赵"}三个元素
//删除容器中key为5的元素
mapA.erase(5);    
//删除mapA的所有元素
mapA.clear();           //容器为空

6.删除

map.find(key);   查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();
map.count(keyElem);   //返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1
map<int,string>::iterator it=mapStu.find(3);
if(it == mapStu.end())
{//没找到
}
else
{//找到了pair<int, string> pairStu = *it;int iID = pairStu.first;      //或   int  iID = it->first;string strName = pairStu.second;    //或   string strName = it->second;
}
map.lower_bound(keyElem);  //返回第一个key<=keyElem元素的迭代器。
map.upper_bound(keyElem);      //  返回第一个key>=keyElem元素的迭代器。

例如: mapStu是用map<int,string>声明的容器,已包含{1,”小李”}{3,”小张”}{5,”小王”}{7,”小赵”}{9,”小陈”}元素。

map<int,string>::iterator it;
it = mapStu.lower_bound(5);  //it->first==5    it->second=="小王"
it = mapStu.upper_bound(5);   //it->first==7   it->second=="小赵"
it = mapStu.lower_bound(6);  //it->first==7    it->second=="小赵"
it = mapStu.upper_bound(6);    //it->first==7   it->second=="小赵"
map.equal_range(keyElem);   //返回容器中key与keyElem相等的上下限的两个迭代器。下限是闭区间,上限是开区间,如[beg,end)。以上函数返回两个迭代器,而这两个迭代器被封装在pair中。

例如:

map<int,string> mapStu; //往mapStu容器插入元素{1,"小李"}{3,"小张"}{5,"小王"}{7,"小赵"}{9,"小陈"}
pair< map<int,string>::iterator , map<int,string>::iterator > pairIt = mapStu.equal_range(5);
map<int, string>::iterator itBeg = pairIt.first;
map<int, string>::iterator itEnd = pairIt.second;
//此时 itBeg->first==5  ,  itEnd->first == 7,
itBeg->second=="小王", itEnd->second=="小赵"

Multimap 案例:

//1个key值可以对应多个valude(分组) 
//公司有销售部 sale (员工2名)、技术研发部 development (1人)、财务部 Financial (2人) 
//人员信息有:姓名,年龄,电话、工资等组成
//通过 multimap进行 信息的插入、保存、显示
//分部门显示员工信息#include <iostream>
#include <string>
#include <map>
using namespace std;class Person
{
public:Person(string name,int age){m_name = name;m_age = age;}string m_name;int m_age;
protected:
private:};int main(void)
{Person p1("张三",32),p2("李四",33),p3("王二",34),p4("麻子",35),p5("赵五",36);multimap<string, Person> map;map.insert(make_pair("Sale", p1));map.insert(make_pair("Sale", p2));map.insert(make_pair("Development", p3));map.insert(make_pair("Development", p4));map.insert(make_pair("Financial", p5));for (multimap<string, Person>::iterator it = map.begin(); it != map.end();it++){cout << it->first << "\t" << (it->second).m_name <<endl;}int num = map.count("Development");cout << "开发部的人数:" << num << endl;cout << "开发部的员工信息:" << endl;multimap<string, Person>::iterator new_it = map.find("Development");int cnt = 0;while (new_it != map.end() && cnt < num ){if (new_it->second.m_age == 32){new_it->second.m_name = "SB";}cout << new_it->first << "\t" << (new_it->second).m_name << endl;new_it++;cnt++;}cout<<"Hello!"<<endl;system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移动APP接口安全性设计

移动APP接口是怎么保证安全性的&#xff0c;可以采用https&#xff0c;或者是非对称加密。 接口加密的目的是防止被别人用抓包工具&#xff0c;抓包后篡改数据。 关于加密算法常见的有对称加密&#xff08;DES&#xff09;和非对称加密&#xff08;RSA&#xff09; 对称加密&am…

掉头

掉头技巧 掉头前打左灯、减速(至五公里左右)甚至停下&#xff0c;注意观察路况&#xff0c;同时密切注意来往车辆情况(尤其是远一点但车速快的)&#xff0c;必要时停车等待。操作方法 1、在较宽广的道路上&#xff0c;应尽量地应用大遇回一次顺车掉头。如在有交通指挥人…

深入理解 Git 的实现原理

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 我一直很佩服能静心细读各种官方文档的人&#xff0c;此文转自&#xff1a;https://www.cnblogs.com/mamingqian/p/9711975.html 原作者…

STL之容器小结

一、理论提高&#xff1a;所有容器提供的都是值&#xff08;value&#xff09;语意&#xff0c;而非引用&#xff08;reference&#xff09;语意。容器执行插入元素的操作时&#xff0c;内部实施拷贝动作。所以STL容器内存储的元素必须能够被拷贝&#xff08;必须提供拷贝构造函…

超车

概念 超车&#xff0c;即车辆经过另一辆车的侧面&#xff0c;从后面超过前面同方向行驶的车辆。用于超车的车道一般为内侧车道&#xff0c;即较接近道路中心而离路肩较远的车道。在靠右行驶的地区&#xff0c;超车道为靠左的车道;在靠左行驶的地区&#xff0c;超车道为靠右的…

STL之函数对象和谓词

1.函数对象 重载函数调用操作符的类&#xff0c;其对象常称为函数对象&#xff08;function object&#xff09;&#xff0c;即它们是行为类似函数的对象。一个类对象&#xff0c;表现出一个函数的特征&#xff0c;就是通过“对象名(参数列表)”的方式使用一个类对象&#xff…

安装 Git ( Windows、linux、Mac)

安装 Git 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 是时候动手尝试下 Git 了&#xff0c;不过得先安装好它。有许多种安装方式&#xff0c;主要分为两种&#xff0c;一种是通过编…

会车

概念 会车&#xff0c;即反向行驶的列车、汽车等同时在某一地点交错通过。 会车攻略 一看&#xff0c;看对向来车的车型、速度和装载情况&#xff0c;前方道路的宽度、坚实情况&#xff0c;路旁行人、车辆情况&#xff0c;路旁停车以及障碍物情况等; 二算&#xff0c;…

FormsAuthenticationTicket基于forms的验证

构建基于forms的验证机制过程如下&#xff1a; 1,设置IIS为可匿名访问和asp.net web.config中设置为form验证 2,检索数据存储验证用户&#xff0c;并检索角色(如果不是基于角色可不用) 3,使用FormsAuthenticationTicket创建一个Cookie并回发到客户端&#xff0c;并存储 角色到票…

通过公共汽车站

要求 通过班车站&#xff0c;应降低速度慢行&#xff0c;挂一挡通过&#xff0c;注意左右仔细查看。操作方法 1、减速慢行&#xff0c;注意观察公共汽车周围的交通情况&#xff0c;以防突然情况的出现; 2、在超越公共汽车时&#xff0c;注意提防公共汽车起步后突然向左转…

STL之函数适配器

1.理论知识 2.常用函数适配器 标准库提供一组函数适配器&#xff0c;用来特殊化或者扩展一元和二元函数对象。常用适配器是&#xff1a; 1绑定器&#xff08;binder&#xff09;: binder通过把二元函数对象的一个实参绑定到一个特殊的值上&#xff0c;将其转换成一元函数对象…

真正理解 git fetch, git pull 以及 FETCH_HEAD

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 真正理解 git fetch, git pull 要讲清楚git fetch&#xff0c;git pull,必须要附加讲清楚git remote&#xff0c;git merge 、远程rep…

pyqt5 + pyinstaller 制作爬虫小程序

环境:mac python3.7 pyqt5 pyinstaller ps: 主要是熟悉pyqt5, 加入了单选框 输入框 文本框 文件夹选择框及日历下拉框 效果图: pyqt5 主程序文件 # -*- coding: utf-8 -*- # Author: Mehaei # Date: 2019-07-10 13:02:56 # Last Modified by: Mehaei # Last Modified time…

通过学校区域

通过学校区域的要求 应观察前后左右的交通情况&#xff0c;适时减速慢行&#xff0c;不得鸣喇叭和与学生抢行。 操作方法 当驾驶车辆行至学校附近或有注意儿童标志路段时&#xff0c;一定要及时减速&#xff0c;注意观察道路两侧或周围的情况&#xff0c;时刻堤防学生横…

axios中出现两次请求,OPTIONS请求和GET请求

在项目中发现ajax中出现两次请求&#xff0c;OPTIONS请求和GET请求 查看到浏览器NetWork有两次请求&#xff0c;请求url一样&#xff1a; 查找原因是浏览器对简单跨域请求和复杂跨域请求的处理区别。 XMLHttpRequest会遵守同源策略(same-origin policy). 也即脚本只能访问相同协…

笔试面试收获(持续更新中)

1. Internet 是有ARPANET发展而来 2. NFS&#xff08;Network File System&#xff09;即网络文件系统 3. OSI参考模型七层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff08;IP,路由器&#xff0c;三层交换机&#xff09;&#xff0c;传输层&#xff…

Linux 安装 配置 Maven

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.需要提前安装JDK&#xff0c;并且配置环境变量 请参考&#xff1a;https://blog.csdn.net/jiangyu1013/article/details/84321146 2.…

Threading in C#

这里推荐一些C#编程多线程的学习资料&#xff1a; http://knowledge.swanky.wu.googlepages.com/threading_in_c_sharp.html Ebook in English&#xff1a;http://cid-068f7d75d8585700.skydrive.live.com/self.aspx/ebook/threading.pdf 一些demo&#xff1a;http://cid-068f7…

经理人如何与这“六种人”打交道?

在职场中&#xff0c;我们要与不同身份、不同年龄、不同岗位、不同性别、不同性格的人打交道。在平时的实际工作接触中&#xff0c;善于与不同人打交道的经理人&#xff0c;会根据不同的情况用不同的态度和方式来对待之。 1、如何与死板的人打交道 与这样的人交往&#xff0c…

[Git高级教程 (一)] 通过 Tag 标签回退版本修复 bug

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1 前言 本系列之所以取名”Git高级教程”&#xff0c;主要是教大家解决实际工作中遇到的问题&#xff0c;要求读者会基本的Git用法和命令…