C++ map和vector向量使用方法

C++ map用法

C++ 中 map 提供的是一种键值对容器,里面的数据都是成对出现的,如下图:每一对中的第一个值称之为关键字(key),每个关键字只能在 map 中出现一次;第二个称之为该关键字的对应值。

map的使用

  1. 需要导入头文件
#include <map> // STL头文件没有扩展名.h
  1. map对象是一个模版类,需要关键字和存储对象两个模版参数
std::map<int , std::string> person;

定义map类型,是有模板的,他接受三个参数:
第一个参数是键的数据类型
第二个参数是值的数据类型
第三个参数是排序规则,不写的话就按照默认的排序规则,也就是按照键的升序

  1. 可以对模版进行类型定义使其使用方便
typedef std::map<int , std::string> MAP_INI_STRING;
MAP_INI_STRING person;

map的构造

1、map 最基本的构造函数;

std::map<int , std::string> mapPerson;

2、map 添加数据;

  1. insert 函数插入 pair 数据
std::map < int , std::string > mapPerson;
mapPerson.insert(pair < int,string > (1,"Jim"));

2)insert 函数插入 value_type 数据

mapPerson.insert(std::map < int, std::string > ::value_type (2, "Tom"));

3)用数组方式插入数据

mapPerson[3] = "Jerry";

map数据的遍历

三种最常用的遍历方法:
1)前向迭代器

std::map < int ,std::string > ::iterator it;std::map < int ,std::string > ::iterator itEnd;it = mapPerson.begin();itEnd = mapPerson.end();while (it != itEnd) {cout<<it->first<<' '<<it->second<<endl;  it++;
}

2)反向迭代器

std::map < int, string > ::reverse_iterator iter;  
for(iter = mapPerson.rbegin(); iter != mapPerson.rend(); iter++) cout<<iter->first<<"  "<<iter->second<<endl;  

3)数组形式

mapPerson.insert(std::map<int, std::string>::value_type (1, "Tom"));
mapPerson[2] = "Jim";
mapPerson[3] = "Jerry";int nSize = mapPerson.size();
for(int n = 1; n <= nSize; n++)qDebug()<<QString::fromStdString(mapPerson[n]);

三种都是遍历,建议使用前向迭代器,慎用使用数组形式(角标开始位置谨慎)。

map中元素的查找

find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。

 map<int ,string > ::iterator l_it;; l_it = maplive.find(112);if(l_it == maplive.end())cout<<"we do not find 112"<<endl;else cout<<"wo find 112"<<endl;

map中元素的删除

如果删除112;

iterator erase(iterator it)	;//通过一个条目对象删除
iterator erase(iterator first,iterator last);	//删除一个范围
size_type erase(const Key&key);	//通过关键字删除
clear()//就相当于enumMap.erase(enumMap.begin(),enumMap.end());

map中swap的用法

Map中的swap不是一个容器中的元素交换,而是两个容器交换;
示例:

 #include <map> #include <iostream>using namespace std;int main( ){map < int, int > m1, m2, m3;map < int, int >::iterator m1_Iter;m1.insert ( pair < int, int >  ( 1, 10 ) );m1.insert ( pair < int, int >  ( 2, 20 ) );m1.insert ( pair < int, int >  ( 3, 30 ) );m2.insert ( pair < int, int >  ( 10, 100 ) );m2.insert ( pair < int, int >  ( 20, 200 ) );m3.insert ( pair < int, int >  ( 30, 300 ) );cout << "The original map m1 is:";for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout << " " << m1_Iter->second;cout   << "." << endl;// This is the member function version of swap//m2 is said to be the argument map; m1 the target mapm1.swap( m2 );cout << "After swapping with m2, map m1 is:";for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout << " " << m1_Iter -> second;cout  << "." << endl;cout << "After swapping with m2, map m2 is:";for ( m1_Iter = m2.begin( ); m1_Iter != m2.end( ); m1_Iter++ )cout << " " << m1_Iter -> second;cout  << "." << endl;// This is the specialized template version of swapswap( m1, m3 );cout << "After swapping with m3, map m1 is:";for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout << " " << m1_Iter -> second;cout   << "." << endl;
}

map的sort问题

Map中的元素是自动按key升序排序,所以不能对map用sort函数:
示例:

 #include <map> #include <iostream>using namespace std;int main( ){map < int, int > m1;map < int, int >::iterator m1_Iter;m1.insert ( pair < int, int >  ( 1, 20 ) );m1.insert ( pair < int, int >  ( 4, 40 ) );m1.insert ( pair < int, int >  ( 3, 60 ) );m1.insert ( pair < int, int >  ( 2, 50 ) );m1.insert ( pair < int, int >  ( 6, 40 ) );m1.insert ( pair < int, int >  ( 7, 30 ) );cout << "The original map m1 is:"<<endl;for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout <<  m1_Iter->first<<" "<<m1_Iter->second<<endl;
}

map的基本操作函数

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

begin()                  返回指向 map 头部的迭代器clear()                 删除所有元素count()                  返回指定元素出现的次数empty()                 如果 map 为空则返回 trueend()                     返回指向 map 末尾的迭代器equal_range()        返回特殊条目的迭代器对erase()                   删除一个元素find()                     查找一个元素get_allocator()      返回map的配置器insert()                  插入元素key_comp()          返回比较元素key的函数lower_bound()     返回键值>=给定元素的第一个位置max_size()            返回可以容纳的最大元素个数rbegin()                返回一个指向map尾部的逆向迭代器rend()                   返回一个指向map头部的逆向迭代器size()                    返回map中元素的个数swap()                 交换两个mapupper_bound()    返回键值>给定元素的第一个位置value_comp()       返回比较元素value的函数

完整代码示例

#include<iostream>
using namespace std;
#include <map> // STL头文件没有扩展名.hmap<string, string> Country;
int main()
{int num;string key, value;cout << "请输入要添加的键值对个数:";cin >> num;cout << "\n";//========== 输入操作 ==========//用数组方式插入数据for (int i = 0; i < num; i++){cout << "键:";cin >> key;cout << "值:";cin >> value;Country[key] = value;}cout << "\n";/*//insert 函数插入 value_type 数据for (int i = 0; i < num; i++){cout << "键:";cin >> key;cout << "值:";cin >> value;Country.insert(map<string, string>::value_type(key, value));}cout << "\n";//insert函数插入pair数据for (int i = 0; i < num; i++){cout << "键:";cin >> key;cout << "值:";cin >> value;Country.insert(pair<string, string>(key, value));}cout << "\n";*///========== 输出操作 ==========/*//反向迭代器遍历输出map<string, string>::reverse_iterator iter;for (iter = Country.rbegin(); iter != Country.rend(); iter++)cout << iter->first << " " << iter->second << endl;//前向迭代器遍历输出map<string, string>::iterator it_Begin;it_Begin = Country.begin(); // begin() 返回指向map头部的迭代器map<string, string>::iterator it_End;it_End = Country.end(); //end() 返回指向 map 末尾的迭代器while (it_Begin != it_End){cout << it_Begin->first << " " << it_Begin->second << endl;it_Begin++;}*/return 0;
}

运行结果

前向迭代器输出:

反向迭代器输出:

说明:map中的元素是自动按key升序排序
用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是不能在插入数据的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值。


什么是vector?

在C++中,vector是一个十分有用的容器。它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据

容器特性

1.顺序序列
顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。

2.动态数组
支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。提供了在序列末尾相对快速地添加/删除元素的操作。

3.能够感知内存分配器的(Allocator-aware)
容器使用一个内存分配器对象来动态地处理它的存储需求。

基本操作

  1. vector的声明及初始化

c++中必须要包含#include <vector>

#include <vector>
vector <T> vec; //T为各种数据类型,可以是基本类型,也可以是自己定义的数据类型
vector <T> vec[20]; //定义了一个二维数组,vec[i]就是一个vector<T>动态数组

不难看出看出vector是一个模板类
更多初始化方式:

vector<int> a; //声明一个int型向量a
vector<int> a(10); //声明一个初始大小为10的向量
vector<int> a(10, 1); //声明一个初始大小为10且初始值都为1的向量
vector<int> b(a); //声明并用向量a初始化向量b
vector<int> b(a.begin(), a.begin() + 3); //将a向量中从第0个到第2个(共3个)作为向量b的初始值
//也可以通过以下方式初始化
int n[] = { 1, 2, 3, 4, 5 };
vector<int> a(n, n + 5); //将数组n的前5个元素作为向量a的初值
vector<int> a(&n[1], &n[4]); //将n[1] - n[4]范围内的元素作为向量a的初值
  1. vector 输入输出及访问
    直接用cin>>a[i];或者cout<<a[i];输入输出即可
  2. vector的遍历
    第一种方式(类似于数组遍历):
vector<int> a;
for (int i = 0; i < a.size(); i++)
{cin >> a[i];cout << a[i];
}

第二种方式(vector迭代器遍历):

vector <int> a;
vector <int> ::iterator iter;
for (iter = a.begin(); iter != a.end(); iter++)
{cin >> *iter;cout << *iter;
}

第三种方式(利用反向迭代器遍历):

vector <int> a;
vector<int>::reverse_iterator iter;
for (iter = a.rbegin(); iter = a.rend(); iter++)
{cin >> *iter;cout << *iter;
}
  1. 向量vector的基本函数
vector <int> a;
vector <int> b;
1. a.size() :返回向量a中元素的个数
2. a.empty() : 判断向量a是否为空,空返回true
3. a.clear() : 清空向量a的所有元素
4.a.insert() : 向向量a中插入
a.insert(pos, 1000) :1000插入到向量a的pos位置上。例:a.insert(a.begin(), 1000);
a.insert(pos, n, 1000) :将1000分别插入到向量a的pos后n个位置上(包含pos)例:a.insert(a.begin(), 3, 1000);
b.insert(b.begin(), a.begin(), a.end()) : 将a.begin(), a.end()之间的全部元素插入到b.begin()5.a.erase : 删除向量a的元素
a.erase(pos) : 删除向量a中pos位置的元素
a.erase(st, ed) : 删除向量中从st到ed之间的元素
6.b.swap(a) : 交换a、b向量
7.比较以及复制
比较:保持 ==!=>>=<<= 的惯有含义;
复制:b = a 将a复制一份赋给b
  1. 算法
    (1) 使用reverse将元素翻转:需要头文件 #include<algorithm>
    reverse(vec.begin(),vec.end());将元素翻转,即逆序排列!
    (在vector中,如果一个函数中需要两个迭代器,一般后一个都不包含)
    (2)使用sort排序:需要头文件 #include<algorithm>
    sort(vec.begin(),vec.end());(默认是按升序排列,即从小到大).
    可以通过重写排序比较函数按照降序比较,如下:
    定义排序比较函数:
bool Comp(const int &a,const int &b)
{return a>b;
}

调用时: sort(vec.begin(),vec.end(),Comp),这样就降序排序。

使用vector注意事项:
1、如果你要表示的向量长度较长(需要为向量内部保存很多数),容易导致内存泄漏,而且效率会很低
2、vector作为函数的参数或者返回值时,需要注意它的写法:double Distance(vector<int>&a, vector<int>&b),其中的“&”绝对不能少!!!


补充:迭代器(Iterators)

迭代器类似于指针。通常,迭代器指向于容器(序列容器或关联容器)中的元素,因此,借助于迭代器,我们可以成功的访问容器中的各个元素。
迭代器中两个非常常用的操作时++(增量操作符)和*(取值操作符)。假设cntItr为某个容器的迭代器,那么如下语句:++cntItr;,其结果为增加cntItr,使其指向容器中的下一个元素,相似的如下语句:*cntItr;,访问cntItr指向的容器中的元素。

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

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

相关文章

采用线性插值的方法 在n个坐标点的基础上 准备添加一个坐标点p 根据给出p的横坐标 计算出p的纵坐标 np.interp()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 采用线性插值的方法 在n个坐标点的基础上 准备添加一个坐标点p 根据给出p的横坐标 计算出p的纵坐标 np.interp() [太阳]选择题 下列选项正确的是&#xff1a; import numpy as np x np.arra…

[架构之路-264]:个性特征 - 到底什么才是工程师文化?

目录 前言&#xff1a; 一、三种类型的商业公司与生存法则 &#xff08;1&#xff09;运营或销售驱动型公司 &#xff08;2&#xff09;产品驱动型公司 &#xff08;3&#xff09;技术驱动型公司 二、工程师文化特征解读1 三、工程师文化特征解读2 &#xff08;1&#…

解决Unity物体速度过快无法进行碰撞检测(碰撞检测穿透)

解决Unity物体速度过快无法进行碰撞检测&#xff08;碰撞检测穿透&#xff09; 一、解决碰撞检测穿透方法一Collision Detection碰撞检测总结&#xff1a; 二、解决碰撞检测穿透方法二 一、解决碰撞检测穿透方法一 首先我们知道只要是跟碰撞相关的基本都是离不开刚体 Rigidbod…

八大排序算法@直接插入排序(C语言版本)

目录 直接插入排序概念算法思想代码实现核心算法&#xff1a;直接插入排序的算法实现&#xff1a; 特性总结 直接插入排序 概念 算法思想 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新…

「C/C++ 01」 深拷贝和浅拷贝

目录 一、概念 1. 浅拷贝 2. 深拷贝 3. 深浅拷贝问题 4. 总结 二、在C的类中实现深拷贝 1. 拷贝构造函数 中实现深拷贝 a. 自己开辟一个新空间&#xff0c;然后将内容拷贝到新空间 b. 借助构造函数来实现深拷贝 2. operator 中实现深拷贝 a. 自己开辟一个新空间&#xff0c;…

One Wire协议应用篇(c语言板)

一.项目简介 利用DS18B20实时检测温度并显示在LCD1602显示屏上&#xff0c;同时可以通过K1,K2,K3,K4设置最高温度和最低温度利用AT24C02可以实现掉电不丢失&#xff0c;最后当检测温度大于或小于最高温时&#xff0c;会在LCD1602显示屏上显示OV:H或OV:L。 二.准备材料 AT89C52、…

ESP32+LVGL笔记(6)-把712k的一二级汉字字库放在SPIRAM

文章目录 1.字库制作2.字库烧录到ESP32-S3的flash2.1 配置好分区文件2.2 汉字库文件烧录到ESP32的flash 3.将字库从 flash 拷贝到 SPIRAM3.1 工程配置中有关 SPIRAM 部分3.2 将汉字库从flash拷贝到SPIRAM的代码3.3 在进入lvgl之前调用函数 copyHZK_from_flash_to_SPIRAM 在前面…

Python入门知识点分享——(八)文件的open方法

学完了Python当中的数据类型&#xff0c;下一步我们来了解如何用Python语言打开文件并添加内容。 目录 file mode buffering encoding errors newline closefd opener 函数 打开文件需要用到open函数&#xff0c;完整的语法格式如下所示&#xff0c;为了演示方便&…

【Linux系统基础】(1)Linux基础命令全面详解

在计算机世界中&#xff0c;Linux操作系统以其稳定性、安全性和开源性而受到广大程序员和系统管理员的喜爱。然而&#xff0c;对于初学者来说&#xff0c;Linux的命令行界面可能会显得有些复杂和难以理解。本文将详细介绍一些常用的Linux基础命令&#xff0c;帮助你更好地理解和…

TLC2543(12位A/D转换器)实现将输入的模拟电压显示到数码管上

代码&#xff1a; #include <reg51.h> #define uchar unsigned char #define uint unsigned int// 数码管0-9 unsigned char seg[] {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; sbit SDO P1^0; sbit SDI P1^1; sbit CS P1^2; sbit CLK P1^3; s…

【C语言】打印内存数据

C语言&#xff0c;用函数封装&#xff1a;16进制打印unsigned char *p指向的内存&#xff0c;长度为int l。16个字节&#xff0c;换一次行。16个字节用一个字符串缓存&#xff0c;一次打印。 以下是一个使用函数封装的C语言代码&#xff0c;用于以16进制格式打印unsigned char …

MyBatis——MyBatis的延迟加载

MyBatis的延迟加载&#xff08;一对多查询案例&#xff09; 1.什么是延迟加载&#xff1f; 开启延迟加载后&#xff0c;在真正使用数据的时候才发起级联查询&#xff0c;不用的时候不查询。 2.pojo User类&#xff1a; package com.wt.pojo;import java.io.Serializable; …

计算机毕业设计------JSP教务处学生成绩管理系统

项目介绍 本项目包含管理员、教师、学生三种角色&#xff1b; 用户角色包含以下功能&#xff1a; 修改密码,查看自己的信息,查看自己的成绩,登录界面等功能。 管理员角色包含以下功能&#xff1a; 修改示例,增删改查学生信息,增删改查教师信息,增删改查课程信息,管理员修改…

电机控制 相关基础概念

基本概念: 定子或者转子上有铁心或者绕铜线的地方,绕铜线的地方叫槽,而将槽分开的叫齿,将所有的齿连起来的部位较轭部。 磁感应强度与磁场强度之间的关系可以通过以下公式表示: B=μH 其中,B 是磁感应强度,H 是磁场强度,μ 是磁导率。这个关系表明,在给定磁场强度下…

Golang 通用代码生成器仙童发布 2.4.0 电音仙女尝鲜版一及其介绍两个模式的视频

Golang 通用代码生成器仙童发布 2.4.0 电音仙女尝鲜版一及其介绍两个模式的视频 Golang 通用代码生成器仙童已发布 2.4.0 电音仙女尝鲜版一及其介绍视频。视频请见&#xff1a; 正常模式&#xff1a; https://www.bilibili.com/video/BV1fw411V77i/ 哑数据模式&#xff1a;…

@z-utils组 重构和自动化实现

highlight: monokai theme: github 包简介 z-utils组 是一个可以在vue/react/pure js 中使用的工具包&#xff0c;它包含三个子类&#xff0c;分别为 z-utils/base, z-utils/react, z-utils/vue 三个分别在不同区域使用。 他是原 zzy-javascript-devtools 的重构版本&#xf…

嵌入式系统复习--Thumb指令集

文章目录 上一篇Thumb指令集概述Thumb指令详细介绍数据处理指令数据存储指令转移指令异常中断指令 下一篇 上一篇 嵌入式系统复习–ARM指令集(二) Thumb指令集概述 在编写Thumb指令时&#xff0c;先要用伪指令CODE16声明&#xff08;ADS的编译环境下&#xff09;&#xff0c…

程序设计的思想

程序设计思想是指在程序设计过程中所采用的一种思维方式&#xff0c;它是程序设计的灵魂和基础。程序设计思想的正确与否直接关系到程序的质量和可维护性。在实际的程序设计中&#xff0c;我们需要遵循一定的程序设计思想&#xff0c;以确保程序的正确性、可读性和可维护性。 …

序列化和反序列化对比分析,序列化和反序列化输出十个学生信息截图

序列化和反序列化是数据处理中的两个相对的概念&#xff0c;通常用于对象的存储和传输。下面是对这两个过程的对比分析&#xff1a; 序列化&#xff08;Serialization&#xff09; 定义 目的&#xff1a; 将对象的状态信息转换成可以存储或传输的形式&#xff08;如XML, JSO…

循环渲染ForEach

目录 1、接口说明 2、键值生成规则 3、组件创建规则 3.1、首次渲染 3.2、非首次渲染 4、使用场景 4.1、数据源不变 4.2、数据源组项发生变化 4.3、数据源数组项子属性变化 5、反例 5.1、渲染结果非预期 5.2、渲染性能降低 Android开发中我们有ListView组件、GridVi…