C++| STL之迭代器和vector

前言:在Leetcode进行手撕代码练习的时候,C++经常能碰到不定长vector的处理,所以把vector常用的知识和使用方法都汇总了一下。迭代器在各种STL容器中都能见到,顺便把迭代器说一下。

迭代器和vector

迭代器

概念

迭代器:是C++STL中一种检查容器内元素并遍历元素的数据类型,通常用于对C++中各种容器内元素的访问,与指针非常类似。

常见容器:string、vector、deque、list、set等。

基本上C++STL容器的迭代器使用都差不多,可以用来遍历和访问容器。

不同的容器有不同迭代器,因为不同容器本身实现的原理结构不同,但是迭代器的功能是相同的。迭代器帮忙实现了好了遍历访问容器的方式,不需要自己去重新编写相应的功能。

常见操作

迭代器定义:

cpp 复制代码
vector<int> ::iterator it;//读写
std::vector<int>::const_iterator it;//只读,不可以修改

begin()和end()函数:begin()就是指向容器第一个元素的迭代器,end()是指向容器最后一个元素的下一个位置的迭代器。

正序遍历容器:

cpp 复制代码
vector<int> ::iterator it;// 读写
for( it = vector.begin(); it != vector.end(); it++ )
	cout<<*it<<endl;

逆向遍历容器:

cpp 复制代码
vector<int> ::iterator it;// 读写
 for( std::vector<int>::reverse_iterator it = v.rbegin(); it!=v.rend();it++ )
    cout<<*it<<endl;

不同容器和迭代器的区别

迭代器 特点 支持
输入迭代器 只读 ++、==、!=
输出迭代器 只写 ++
前向迭代器 读写,只能向前推进 ++、==、!=
双向迭代器 读写,能向前向后推进 ++、--
随机访问迭代器 读写,跳跃读取 ++、--、[n]、-n、<、<=、>、>=
容器 迭代器
vector 随机访问
string 随机访问
deque 随机访问
list 双向
set 双向
map 双向
stack 不支持迭代器
queue 不支持迭代器

vector

vector就是不定长数组,根据需要自动增长和缩小。

原理的话,增长后大小如果连续存储空间不了的话,需要另外开辟一块足够大小的空间,复制过去,再释放原来的空间。

vector和string有点像,很多功能上会比较相似。string的话可以参考我的另一篇C++| STL之string,可以vector和string对比着看。

头文件:

cpp 复制代码
#include <vector>

创建

cpp 复制代码
vector<int>vec; // 创建一个整数的空vector
vector<int> vec(5);// 创建一个包含 5 个整数的vector,里面的值默认为0
vector<int> vec(5,10);// 创建一个包含 5 个整数的vector,里面的值默认为10
vector<int> vec = {1, 2, 3, 4}; // 初始化一个包含元素的vector

大小和容量

length是string特有的,sizeof计算vector和元素数量没有意义。

cpp 复制代码
int size = vec.size(); // 获取vector中的元素数量
vec.capacity();// 重新分配内存之前,vector对象能包含的最大字符数
bool isEmpty = vec.empty();// 判断是否为空

分配内存

和string的是一样的。

函数:

  • reserve():为容器预留足够的空间,避免不必要的重复分配,减少系统开销,影响capacity。
  • resize():调整容器中有效数据区域的尺寸,如果尺寸变小,多余的截掉;若尺寸变大,第二个参数填充,影响size。

在做leetcode题目的时候,如果预先就知道会有多少元素,可以预先分配capacity,也就是用reserve来分配。从而来避免不定长的string和vector在不定长增加的时候,反复重新开辟空间的的系统开销。

遍历

看过了迭代器的部分,就知道vector是随机访问迭代器,可以用下标也可以用迭代器。

cpp 复制代码
// vector<int>vec; 
// 1. 下标
for(int i=0;i<vec.size();i++)
	cout<<vec[i]<<endl;
// 2. 迭代器
vector<int> ::iterator it;// 读写
for( it = vec.begin(); it != vec.end(); it++ )
	cout<<*it<<endl;

添加

cpp 复制代码
vec.push_back(3); // 将整数3添加到vector的末尾

删除

cpp 复制代码
vec.erase(vec.begin()+2);// 删除第三个元素
vec.pop_back(); //删除vec的最后一个元素

访问

cpp 复制代码
// 1. 下标
int a=vec[0];
// 2. at()
int b=vec.at(0);
// 3. 访问首元素和尾元素,可以用来模拟栈和队列
int f=vec.front();// 首元素
int l=vec.back();// 尾元素

查找

find也适用于普通的数组,很多容器都有这个功能,对于非线性的结构就没法限制范围的搜索了。

cpp 复制代码
// 1. 不限范围
if(vec.find(x) != vec.end())
	cout<<x<<"存在"<<endl
// 2. 限制范围
if(vec.find(vec.begin(),vec.end(),x) != vec.end())
	cout<<x<<"存在"<<endl

清空

cpp 复制代码
vec.clear(); // 清空vector
相关推荐
Buleall4 分钟前
期末考学C
java·开发语言
重生之绝世牛码6 分钟前
Java设计模式 —— 【结构型模式】外观模式详解
java·大数据·开发语言·设计模式·设计原则·外观模式
小蜗牛慢慢爬行12 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
Algorithm157622 分钟前
云原生相关的 Go 语言工程师技术路线(含博客网址导航)
开发语言·云原生·golang
shinelord明31 分钟前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
Monly2137 分钟前
Java(若依):修改Tomcat的版本
java·开发语言·tomcat
boligongzhu38 分钟前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
Eric.Lee202139 分钟前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
小俊俊的博客39 分钟前
海康RGBD相机使用C++和Opencv采集图像记录
c++·opencv·海康·rgbd相机
7yewh41 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux