[STL]vector常见用法详解

2023-11-14

目录

引入

常见用法介绍

1. vector的定义

2. vector容器内元素的访问

3. vector常用函数实例解析

1)push_back()

2)pop_back()

3)size()

4)clear()

5)insert()

6)erase()

vector的常见用途 

1. 存储数据

2. 用邻接表存储图


引入

vector翻译为向量,但你可以理解为“变长数组”,即vector会根据长度需要而自动改变。在算法题目中,会碰到只用普通数组会超内存的情况,这个时候vector的运用会使问题的解决便捷很多。另外,vector还可以用来以邻接表的方式存储图,这对无法使用邻接矩阵的题目(结点数太多)、以及害怕用指针实现邻接表的读者十分友好。

如果要使用vector,需要添加vector头文件,即#include<vector>。如果你之前只有C语言编程经验,记得在头文件下面添加一句using namespace std;

常见用法介绍

1. vector的定义

单独定义一个vector:

vector<typename> name;

上面这个定义相当于是一维数组name[SIZE],不过其长度可以根据需要进行变化,比较节省空间。说白了就是“变长数组”。

关于typename,可以是任何基本类型,如int, char, double, 结构体,也可以是其他STL容器。

需要注意的是,如果typename是STL容器(带<>),定义的时候需要在>>之间加上空格,因为一些使用C++11之前标准的编译器会将它当成移位操作,导致编译错误。

示例如下:
 

vector<int> name;
vector<char> name;
//如果typename是STL容器,>>需要加空格 
vector<vector<int> >name; 

读者不难发现,示例三给出了vector二维数组的定义,你可以简单理解为两个维度都可以变长的二维数组。

然后来看定义vector数组的方法:

vector<typename> Arrayname[arraySize];

这样Arrayname[0]~Arrayname[arraySize-1]中每一个都是一个vector容器。

与vector<vector<int> > name不同的是,这种写法的一位长度已经固定为arraySize,另一维才是“变长”的。

2. vector容器内元素的访问

这里引入一个概念——迭代器。迭代器(iterator)可以理解为一种类似指针的东西,定义为:

vector<typename>::iterator it;

这样it就是一个vector<typename>::iterator型的变量,typename为定义vector时填写的类型。

vector<int>::iterator it;
//typename为int
vector<double>::iterator it;
//typename为double

这样,我们就得到了迭代器it,并且可以通过*it来访问vector里的元素。

例如,有这样定义的一个vector容器:

vector<int>vi;
for(int i = 1; i <= 5; i++){ 
	vi.push_back(i);
	//push_back(i)在vi的末尾添加元素i 
}
//循环结束后vi中元素有1 2 3 4 5 

那我们可以通过类似下标和指针访问数组的方式来访问容器内的元素:

#include <iostream>
#include <vector>
 using namespace std;
 int main(){
 	vector<int> vi;
 	for(int i = 1; i <= 5; i++){
 		vi.push_back(i);
	}
	 //vi.begin()为取vi的首元素地址,而it指向这个地址
	vector<int>::iterator it = vi.begin();
	for(int i = 0; i < 5; i++){
		printf("%d ", *(it+i));
	} 
	return 0;
 }
 
 /*
 result:
 1 2 3 4 5 
 */ 

从这里看出,vi[i]和*(vi.begin()+i)是等价的。

既然上面说到了begin()函数的作用为取vi的首元素地址,那么还需要提到end()函数。与begin()不同的是,end()并不是取vi的尾元素地址,而是取尾元素地址的下一个地址。end()作为迭代器末尾标志,不存储任何元素。

除此之外,迭代器还实现了两种自加操作:++it和it++(自减操作同理),于是有了另一种遍历vector元素的方法。

#include <iostream>
#include <vector>
 using namespace std;
 int main(){
 	vector<int> vi;
 	for(int i = 1; i <= 5; i++){
 		vi.push_back(i);
	}
	//vector的迭代器不支持it < vi.end()写法,改用!=作为循环条件 
	for(vector<int>::iterator it = vi.begin(); it != vi.end(); it++){
		printf("%d ", *it);
	} 
	return 0;
 }
 
 /*
 result:
 1 2 3 4 5 
 */ 

最后需要指出,在常见STL容器中,只有在vector和string中,才允许使用vi.begin() + 3这种迭代器加上整数的做法。

3. vector常用函数实例解析

1)push_back()

顾名思义,push_back(i)就是在vector后面加一个元素i,时间复杂度为O(1)。

示例如下:

#include <iostream>
#include <vector>
using namespace std;
int main(){
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i);
	for(int i = 0; i < vi.size(); i++)
		cout<<vi[i]<<" ";
	//size()函数会给出vi中元素的个数	
	return 0;
}
/*
result: 1 2 3 
*/ 

2)pop_back()

有添加就会有删除,pop_back()用于删除vector的尾元素,时间复杂度为O(1)。

示例如下:

#include <iostream>
#include <vector>
using namespace std;
int main(){
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i); //将1 2 3依次插入vi末尾 
	vi.pop_back(); //删除vi的尾元素3 
	for(int i = 0; i < vi.size(); i++)
		cout<<vi[i]<<" ";
	//size()函数会给出vi中元素的个数 
	return 0; 
}
/*
result: 1 2 
*/ 

3)size()

size()用来获得vector中元素的个数,时间复杂度为O(1)。size()返回的是unsigned类型,不过一般来说用%d问题不大,这一点对于所有STL容器都是一样的。

示例如下:

#include <iostream>
#include <vector>
using namespace std;
int main(){
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i); //将1 2 3依次插入vi末尾 
	cout<<vi.size()<<endl; 
	return 0; 
}
/*
result: 3
*/ 

4)clear()

clear()用于清空vector中所有的元素,时间复杂度为O(N),N为vector中元素的个数。

示例如下:

#include <iostream>
#include <vector>
using namespace std;
int main(){
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i); //将1 2 3依次插入vi末尾 
	vi.clear();
	cout<<vi.size()<<endl; 
	return 0; 
}
/*
result: 0
*/ 

5)insert()

insert(it, x)用来向vector的任意一个迭代器it处插入一个元素x,时间复杂度为O(N)。

示例如下:

#include <iostream>
#include <vector>
using namespace std;
int main(){
	vector<int> vi;
	for(int i = 1; i <= 5; i++)
		vi.push_back(i); //将1 2 3 4 5依次插入vi末尾 
	vi.insert(vi.begin() + 2, -1); //将-1插入vi[2]的位置 
	for(int i = 0; i < vi.size(); i++)
		cout<<vi[i]<<" "; 
	return 0; 
}
/*
result: 1 2 -1 3 4 5
*/ 

6)erase()

erase()有两种用法:删除单个元素,删除一个区间内的所有元素。时间复杂度均为O(N)。

删除单个元素:

erase(it)即为删除迭代器为it处的元素。

示例如下:

#include <iostream>
#include <vector>
using namespace std;
int main(){
	vector<int> vi;
	for(int i = 1; i <= 5; i++)
		vi.push_back(i); //将1 2 3 4 5依次插入vi末尾 
	vi.erase(vi.begin() + 2); //删除位于vi[2]处的元素
	for(int i = 0; i < vi.size(); i++)
		cout<<vi[i]<<" "; 
	return 0; 
}
/*
result: 1 2 4 5
*/ 

删除一个区间内的所有元素:

erase(first, last)即删除[first, last)内的所有元素。

示例如下:

#include <iostream>
#include <vector>
using namespace std;
int main(){
	vector<int> vi;
	for(int i = 1; i <= 5; i++)
		vi.push_back(i); //将1 2 3 4 5依次插入vi末尾 
	vi.erase(vi.begin() + 2, vi.begin() + 4);
	//删除vi[2], vi[3] 
	for(int i = 0; i < vi.size(); i++)
		cout<<vi[i]<<" "; 
	return 0; 
}
/*
result: 1 2 5
*/ 

由上面的说法可以知道,如果要删除这个vector内的所有元素,正确的写法是vi.erase(vi.begin(), vi.end()),正如前面所说,vi.end()指向尾元素地址的下一个地址。(当然,更简便的操作是使用vi.clear())。

vector的常见用途 

1. 存储数据

vector本身可以作为变长数组来使用,而且在一些元素不确定的场合可以很好的节省空间

2. 用邻接表存储图

使用vector实现邻接表可以避免使用指针

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[STL]vector常见用法详解 的相关文章

随机推荐

  • CreateRemoteThread的使用(转载)

    先解释一下远程进程 其实就是要植入你的代码的进程 相对于你的工作进程 如果叫本地进程的话 它就叫远程进程 可理解为宿主 首先介绍一下我们的主要工具CreateRemoteThread 这里先将函数原型简单介绍以下 CreateRemoteT
  • Android 特许权限白名单

    1 前言 在项目开发中 需求 app中有恢复出厂设置的功能 分解这个需求的时候 第一反应肯定不是第三方app 恢复出厂设置肯定需要有系统权限 属于系统级的app 然后在看手机系统中的功能 恢复出厂设置功能属于设置模块 找到源码阅读 当然是能
  • 2017-7-17 2-2 不使用&&和

    include
  • tomcat下载和配置(简单,详细)

    下载 官网 http tomcat apache org 找到需要的版本 点击download 在download页面 选择需要下载的 分为压缩版和安装版 我比较推荐压缩版 省事解压缩就好 配置 首先 tomcat7 0以上版本不需要配置环
  • 提高map[key]=value的效率

    当关乎效率时应该在map operator 和map insert之间仔细选择 我们知道 这个表达式 m k v 检查键k是否已经在map里 如果不 就添加上 以v作为它的对应值 如果k已经在map里 它的关联值被更新成v 举例一 考虑插入
  • 搭建第一个Dapp应用(4)——搭建SmartDev-Scaffold——2021.5.3

    搭建第一个Dapp应用 4 搭建SmartDev Scaffold 一丶环境配置 Java gt JDK 1 8 Solidity 0 4 25 Git 下载安装包需要使用Git Gradle 大于6 小于7 使用gradle7会报错 二丶
  • JavaEE规范与系统结构

    JavaEE规范 JavaEE规范是J2EE规范的新名称 早期被称为J2EE规范 其全称是Java 2 Platform Enterprise Edition 它是由SUN公司领导 各厂家共同制定并得到广泛认可的工业标准 JCP组织成员 之
  • Jenkins之定时构建

    1 操作环境 1 Jenkins Jenkins 2 75 2 定时构建 1 定时构建语法 第一个 表示分钟 取值0 59 第二个 表示小时 取值0 23 第三个 表示一个月的第几天 取值1 31 第四个 表示第几月 取值1 12 第五个
  • 由java:local_policy.jar和US_export_policy.jar引发的“血案”

    起因 今天项目上线 上线后监测日志 发现由异常 开始查找问题 进而引发了 血案 线上日志报错如下 Illegal key size 画外音 看到线上项目出现问题心里慌的一批 赶紧扒拉出代码 一行一行对着报错日志查看 最后定位到 AES ae
  • 制作SD卡启动盘(编译烧写u-boot)

    一 SD启动盘制作 将我们的sdfuse q文件夹拷贝到虚拟机Ubuntu的共享目录下 sudo cp samba NFS FTP sdfuse q a 将文件夹复制到 home chen 目录下 cd sdfuse q 进入sdfuse
  • 西门子PLC s7-1200学习之路

    1 Introduction 最近因为一个项目需要使用西门子PLC 买了一个入门级的PLC s7 1200 并完成了一个PLC和PC通过TCP进行通信的小程序 为了防止活干完了 内容就全忘了 所以用一个笔记进行梳理和总结 入门一种语言 需要
  • 专访蒋宇捷:技术管理者应具备哪些能力?(转载)

    摘要 近期 本站记者采访了CSDN社区活跃用户 百度技术经理蒋宇捷 他认为一个合格的技术管理者应该具备深度认知产品 冷静决策 以及良好的沟通能力 还要秉持着技术源于一线 永远不能脱离一线的观念 蒋宇捷 西安交通大学硕士 现任百度技术经理 曾
  • [系统安全] 三十九.Powershell恶意代码检测系列 (1)Powershell基础入门及管道和变量的用法

    您可能之前看到过我写的类似文章 为什么还要重复撰写呢 只是想更好地帮助初学者了解病毒逆向分析和系统安全 更加成体系且不破坏之前的系列 因此 我重新开设了这个专栏 准备系统整理和深入学习系统安全 逆向分析和恶意代码检测 系统安全 系列文章会更
  • 水杯测试用例小记

    水杯测试用例
  • python编写数学公式-Python引入数学函数计算

    Python引入数学函数计算 在利用Python对Abaqus进行相关编程时经常需要用到数学函数 比如三角函数等 在使用这些函数之前需要先引入数学模块 Import math 之后利用时还需要利用层级关系 比如math pi表示 一个示例如
  • go: no such tool “compile“(一次糟糕体验)

    这是一次离谱问题和胡搞一通莫名解决的记录 背景 win11系统下 原有的go1 18更新到go1 19后出现了莫名的go no sucn tool compile 的情况 当时检查go env 如下 PS D Desktop gt go e
  • pycharm使用wsl、SSH

    pycharm wsl 修改apt get源 安装miniconda 配置pycharm SSH Using the Python remote debug server configuration wsl windows sub linu
  • Python10行代码实现模拟百度搜索

    作者主页 士别三日wyx Python模拟百度搜索 1 获取百度搜索接口 2 指定搜索内容 3 UA伪装 4 将响应内容写入文件 5 使用浏览器打开页面 源码如下 1000块钱做个百度 能提出这种要求的客户实乃乙方克星 民族之光 科创永动机
  • 30个落地案例告诉你,区块链到底怎么用

    区块链的商业价值 一千个企业就有一千种解读 唯链 VeChain 起步于2015年 作为国内知名的公链项目之一 它的行事作风一直显得不太 合群 大多数公链生态所追随的热点如DAPP游戏开发 Defi Staking等等 唯链似乎都鲜少参与
  • [STL]vector常见用法详解

    目录 引入 常见用法介绍 1 vector的定义 2 vector容器内元素的访问 3 vector常用函数实例解析 1 push back 2 pop back 3 size 4 clear 5 insert 6 erase vector