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 map
   m1.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 swap
   swap( 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 为空则返回 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的函数

完整代码示例

#include<iostream>
using namespace std;
#include <map> // STL头文件没有扩展名.h

map<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指向的容器中的元素。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

.Net 访问电子邮箱-LumiSoft.Net,好用

序言&#xff1a; 网上找了很多关于.Net如何访问电子邮箱的方法&#xff0c;但是大多数都达不到想要的需求&#xff0c;只有一些 收发邮件。因此 花了很大功夫去看 LumiSoft.Net.dll 的源码&#xff0c;总算做出自己想要的结果了&#xff0c;果然学习诗人进步。 介绍&#xff…

swing快速入门(二十四)绘画板-可调色

注释很详细&#xff0c;直接上代码 上一篇 Look here~ 听我说完再继续看更容易理解&#xff1a; 如果说用之前的绘图方法写一个绘画板你会怎么做&#xff1f;重绘会让之前的内容消失呀&#xff0c;用各种数据结构记录每个像素点的位置或颜色&#xff1f;嘶&#xff0c;感觉很麻…

【数据结构】递归与分治

一.递归 1.递归的概念&#xff1a; 子程序&#xff08;或函数&#xff09;. 接调用自己或通过一系列调用语句间接调用自己&#xff0c;成为递归。 递归是一种描述问题和解决问题的基本方法。 重复地把问题转化为与原问题相似的新问题&#xff0c;直到问题解决为止。 2.递归…

MyBatis 架构分析

文章目录 三层架构一、基础支撑层1.1 类型转换模块1.2 日志模块1.3 反射工具模块1.4 Binding 模块1.5 数据源模块1.6 缓存模块1.6 解析器模块1.7 事务管理模块 二、核心处理层2.1 配置解析2.2 SQL 解析与 scripting 模块。2.3 MyBatis 中的 scripting 模块就是负责动态生成 SQL…

111基于matlab的粒子滤波进行锂离子电池的循环寿命预测

基于matlab的粒子滤波进行锂离子电池的循环寿命预测&#xff0c;输出实验、粒子滤波及自然预测数据结果。程序已调通&#xff0c;可直接运行。 111matlab锂离子电池寿命预测 (xiaohongshu.com)

Git安装和使用教程,并以gitee为例实现远程连接远程仓库

文章目录 1、Git简介及安装2、使用方法2.1、Git的启动与配置2.2、基本操作2.2.1、搭建自己的workspace2.2.2、git add2.2.3、git commit2.2.4、忽略某些文件不予提交2.2.5、以gitee为例实现git连接gitee远程仓库来托管代码 1、Git简介及安装 版本控制&#xff08;Revision cont…

C/C++ 连接访问 MySQL数据库

前面我们已经讲述了MySQL的基础使用&#xff0c;现在我们来看一下如何使用语言来操作数据库。在实际开发中&#xff0c;语言连接MySQL是为了能够在编程语言中与MySQL数据库进行交互和操作。大部分情况我们都是通过语言连接MySQL&#xff0c;建立与MySQL数据库的连接&#xff0c…

springboot实现发送邮件开箱即用

springboot实现发送邮件开箱即用 环境依赖包yml配置Service层Controller层测试 环境 jdk17 springboot版本3.2.1 依赖包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId><ver…

分布式系统架构设计之分布式数据管理

随着互联网时代的不断发展&#xff0c;分布式系统架构成为支撑大规模用户和高并发访问的基础。在构建分布式系统时&#xff0c;分布式系统有着一系列的要求以及对应的核心技术&#xff0c;涉及到数据管理、通信安全性、性能优化、可扩展性设计以及架构演进与版本管理等很多方面…

N字形变换(麻烦的方法)

class Solution:def convert(self, s: str, numRows: int) -> str:#先判断z有多少隔开s_new""index_now0if len(s)<numRows or numRows1:return sfor i in range(numRows-1,-1,-1):exchange0index_exchangeindex_nows_news[index_now]#计算每一层的差距gap_but…

【零基础入门Python】Python参数

✍面向读者&#xff1a;所有人 ✍所属专栏&#xff1a;零基础入门Pythonhttps://blog.csdn.net/arthas777/category_12455877.html 目录 print&#xff08;&#xff09;中的Python结束参数 print&#xff08;&#xff09;中的Python|sep参数 Python的格式转换规则 使用格式…

Vue如何请求接口——axios请求

1、安装axios 在cmd或powershell打开文件后&#xff0c;输入下面的命令 npm install axios 可在项目框架中的package.json中查看是否&#xff1a; 二、引用axios import axios from axios 在需要使用的页面中引用 三、get方式使用 get请求使用params传参,本文只列举常用参数…

java中线程相关的面试题

什么是线程安全&#xff0c;造成线程安全的本质是什么&#xff1f; 什么是线程安全呢&#xff1f; 咱们初步去理解话记住一句话就行&#xff1a;如果一个对象可以安全地被多个线程同时使用&#xff0c;那它就是线程安全的。 为什么并发编程会导致线程不安全&#xff1f; 可见…

用户认证篇

文章目录 1. 如何生成用户认证token令牌1.1 相关表1.2 生成令牌逻辑1.3 最终结果 2. 如何认证用户token令牌2.1 前端组件2.2 TokenAuthenticationFilter2.3 获得登陆用户 3. 如何刷新用户认证 Token 令牌3.1 前端组件3.2 刷新令牌接口 4. 如何模拟用户认证token令牌5. 如何实现…

php学习03-php注释

<?php //单行注释 echo ;//单行注释//单行注释嵌套 /*** 多行注释* 多行注释不允许嵌套*/ $c 12; # 这也是单行注释 #嵌套 /*** 文档注释*/ class Util{/*** 方法注释* param int $num* return int*/function add($num){return 11$num;} }echo 这样会出错的//不会看打到?…

linux的主线程提前子线程退出以及线程分离

主线程提前退出 如果主线程没有等待子线程提前退出&#xff0c;可能会发生以下情况&#xff1a; 子线程继续运行&#xff1a;如果主线程退出&#xff0c;但子线程仍在执行任务&#xff0c;子线程将继续独立运行。子线程的生命周期不受主线程控制&#xff0c;直到子线程自行完成…

基于Springboot的留守儿童爱心网站(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的留守儿童爱心网站(有报告)。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring…

蓝牙物联网在智能家居中的应用前景

物联网智能家居系统是应用物联网技术&#xff0c;在传统家居环境下将各种零散无序的电器整合成统一整体&#xff0c;实现家电的全程自动控制&#xff0c;满足用户高效管理需求的一种新型家居模式。 其主要的子系统有家居感知系统、家庭网络系统、智能家居控制管理系统等&#x…

LINUX 嵌入式应用开发层细节知识(入职体验)

1. 后台进程 一些辅助监测的工作&#xff08;日志系统&#xff0c;OTA升级&#xff0c;云-本地中转) 进程可以设置为守护进程 nohup nohub、&、setsid nohup 是可以忽略所有信号&#xff0c;让程序进入后台进程模式。‘ 2. IPCS -ipc_index 查询IPC目前的使用情况 3.…