浅谈C++|STL之vector篇

news2025/1/19 23:09:42

在这里插入图片描述

一.vector的基本概念

vector是C++标准库中的一种动态数组容器,提供了动态大小的数组功能,能够在运行时根据需要自动扩展和收缩。vector以连续的内存块存储元素,可以快速访问和修改任意位置的元素。

以下是vector的基本概念和特点:

  1. 动态大小:vector可以动态地调整其大小,可以在运行时根据需要添加或删除元素。与静态数组不同,vector不需要在定义时指定固定的元素个数。

  2. 连续存储:vector以连续的内存块存储元素。这样的存储方式使得访问元素变得高效,可以通过索引快速访问和修改任意位置的元素。

  3. 自动扩展和收缩:vector可以根据需要自动扩展以容纳更多的元素,并在需要时自动收缩以节省内存。这样,您无需手动管理内存,vector会自动处理。

  4. 插入和删除:vector提供了多种方法来插入和删除元素。可以在任意位置插入元素,也可以从任意位置删除元素,包括头部和尾部。

  5. 随机访问:vector支持快速的随机访问。可以使用索引来直接访问任意位置的元素,时间复杂度为O(1)。

  6. 迭代器支持:vector提供迭代器来遍历容器中的元素。迭代器可以用于读取和修改容器中的元素,支持正向和反向迭代。

vector是一个非常常用和灵活的容器,适用于需要动态调整大小的数组存储需求。它在许多应用中都很有用,例如数据的动态收集、动态分配的数组、实现栈和队列等。

功能:

vector教据结构和数组非常相似,也称为单端数组

vector与普通数组的区别

不同之处在于数组是静态空间,而vector可以动态扩展

动态扩展

并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间

二.vector赋值操作

vector提供了几种不同的函数和操作符用于赋值操作。以下是常用的vector赋值操作的函数原型:

  1. operator= 操作符:
vector& operator=(const vector& other);

该操作符用于将一个vector赋值给另一个vector,使它们包含相同的元素。该操作符返回一个引用,允许连续赋值。

  1. assign() 函数:
void assign(size_type count, const T& value);
template<typename InputIt>
void assign(InputIt first, InputIt last);
void assign(std::initializer_list<T> ilist);

assign() 函数用于将指定的值、范围或初始化列表中的元素赋值给vector。第一个版本接受指定数量的元素值;第二个版本接受范围指针,可以使用迭代器指定范围;第三个版本接受一个初始化列表。

  1. swap() 函数:
void swap(vector& other);

swap() 函数用于交换两个vector的内容,将当前vector与另一个vector的元素进行交换。

整理成表格,以方便查阅。

函数函数原型描述
operator=vector& operator=(const vector& other);将一个vector赋值给另一个vector,使它们包含相同的元素。
assign()void assign(size_type count, const T& value);将指定数量的元素值赋值给vector
template<typename InputIt> void assign(InputIt first, InputIt last);将范围指针指定的元素赋值给vector
void assign(std::initializer_list<T> ilist);将初始化列表中的元素赋值给vector
swap()void swap(vector& other);交换两个vector的内容。

三.vextor的大小和容量

vector提供了一些函数用于获取容量和大小相关的信息。以下是vector的容量和大小函数的原型:

  1. size() 函数:
size_type size() const;

此函数返回vector当前包含的元素数量,也就是vector的大小。

  1. max_size() 函数:
size_type max_size() const;

该函数返回vector可以容纳的最大元素数量,考虑到系统限制和内存限制。

  1. resize() 函数:
void resize(size_type count);
void resize(size_type count, const T& value);

此函数用于调整vector的大小,可以增加或减少元素的数量。第一个版本将vector的大小调整为指定的 count,第二个版本还可以指定当扩展vector大小时,默认填充的元素值。

  1. capacity() 函数:
size_type capacity() const;

该函数返回当前vector的容量,即能够在重新分配内存之前持有的元素数量,以节省内存重新分配的开销。

  1. reserve() 函数:
void reserve(size_type new_cap);

此函数用于增加vector的容量,使其至少能够容纳指定数量的元素,但不为元素分配实际值。这可以提前分配所需的内存,以减少因调整大小而引起的内存重新分配的次数。

整理成表格:

函数函数原型描述
size()size_type size() const;返回vector当前包含的元素数量,即vector的大小。
max_size()size_type max_size() const;返回vector可以容纳的最大元素数量,受系统限制和内存限制约束。
empty()bool empty() const;判断vector是否为空,若为空则返回true,否则返回false
resize()void resize(size_type count);
void resize(size_type count, const T& value);
调整vector的大小,增加或减少元素数量。
第一个版本将vector的大小调整为指定的count
第二个版本在扩展vector大小时,指定默认的填充元素值。
capacity()size_type capacity() const;返回当前vector的容量,即为元素重新分配内存之前可以容纳的元素数量,以节省内存重新分配的开销。
reserve()void reserve(size_type new_cap);增加vector的容量,使其至少能够容纳指定数量的元素,但不为元素分配实际值。这样可以减少内存重新分配的次数。

四.vector插入和删除

整理成表格:

函数函数原型描述
insert()iterator insert(iterator pos, const T& value);
iterator insert(iterator pos, size_type count, const T& value);
在指定位置插入元素到vector中,并返回插入的位置迭代器。
第一个版本可以插入单个元素。
第二个版本可以插入指定数量的相同元素。
emplace()template <class... Args> iterator emplace(iterator pos, Args&&... args);在指定位置就地构造一个元素,并返回插入的位置迭代器。
erase()iterator erase(iterator pos);
iterator erase(iterator first, iterator last);
vector中删除指定位置或范围的元素,并返回下一个元素的位置迭代器。
clear()void clear();vector中移除所有的元素,使其变为空。
push_back()void push_back(const T& value);将元素添加到vector的末尾。
emplace_back()template <class... Args> reference emplace_back(Args&&... args);vector的末尾就地构造一个元素。
pop_back()void pop_back();移除vector的最后一个元素。

请注意,表中的函数参数使用的是迭代器(iterator),而非常数迭代器(const_iterator)。这是因为插入和删除操作会改变容器的内容,所以需要可变的迭代器来指向和修改元素。

五.vector数据的存取

下面是vector的数据存取操作函数的函数原型整理成表格:

函数函数原型描述
at()reference at(size_type pos);
const_reference at(size_type pos) const;
返回指定位置的元素的引用。
pos超出范围,会抛出out_of_range异常。
operator[]()reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
返回指定位置的元素的引用。
不进行范围检查,使用时需确保索引有效。
front()reference front();
const_reference front() const;
返回vector中第一个元素的引用。
back()reference back();
const_reference back() const;
返回vector中最后一个元素的引用。
data()T* data();
const T* data() const;
返回指向vector中第一个元素的指针。
vector为空,返回空指针。

以上是常用的vector数据存取操作的函数原型。您可以根据需要使用它们来访问和修改vector中的元素。

六.vector的容器交换

vector的容器互换操作可以使用swap()函数来实现。swap()函数可以交换两个容器的内容,具体的函数原型如下:

template <class T, class Alloc>
void swap(vector<T,Alloc>& x, vector<T,Alloc>& y) noexcept;

其中,xy是要互换内容的两个 vector 容器。使用swap()函数可以快速高效地交换两个 vector 的内容,而不需要逐个元素进行复制或移动。

下面是一个简单的示例演示如何使用 swap() 函数交换两个 vector 的内容:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec1 = {1, 2, 3, 4};
    std::vector<int> vec2 = {5, 6, 7, 8};

    // 输出交换前的内容
    std::cout << "vec1: ";
    for (const auto& num : vec1) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    std::cout << "vec2: ";
    for (const auto& num : vec2) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 交换容器内容
    std::swap(vec1, vec2);

    // 输出交换后的内容
    std::cout << "vec1: ";
    for (const auto& num : vec1) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    std::cout << "vec2: ";
    for (const auto& num : vec2) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

运行以上代码,将会输出如下结果:

vec1: 1 2 3 4 
vec2: 5 6 7 8 
vec1: 5 6 7 8 
vec2: 1 2 3 4

通过 swap() 函数,vec1vec2 的内容被互换了。这个操作非常高效,因为只涉及到指针的交换,而不需要逐个元素进行复制或移动。

巧用swap收缩内存空间

swap()函数还可以用于收缩vector内存空间,从而释放不需要的内存。通过将一个空的vector与目标vector进行交换,可以使目标vector的容量缩小到与其当前大小相匹配。

这是因为当swap()函数交换两个vector时,目标vector会获得另一个vector的内存空间,而那个被交换的vector则会获得一个空的内存空间。然后,由于交换后的vector大小与容量相匹配,多余的内存会被释放。

以下是一个示例代码,展示了如何通过swap()函数收缩vector的内存空间:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec;

    // 向vector中添加大量数据
    for (int i = 0; i < 1000000; ++i) {
        vec.push_back(i);
    }

    std::cout << "Size before shrink: " << vec.size() << std::endl;
    std::cout << "Capacity before shrink: " << vec.capacity() << std::endl;

    // 收缩内存空间
    std::vector<int>(vec).swap(vec);

    std::cout << "Size after shrink: " << vec.size() << std::endl;
    std::cout << "Capacity after shrink: " << vec.capacity() << std::endl;

    return 0;
}

运行以上代码,将会输出如下结果:

Size before shrink: 1000000
Capacity before shrink: 1048576
Size after shrink: 1000000
Capacity after shrink: 1000000

通过使用swap()函数将一个空的vector和目标vector交换,我们成功缩小了vec的内存空间,使其容量与其大小相匹配。注意,swap()函数的参数是通过使用临时vector构造的,以避免影响到原始vec的值。

请注意,这种技巧并不适用于C++11标准之前的版本,因为在C++11之前,vector的移动语义不是必须的,而可能导致复制操作而不是交换操作。因此,在使用旧标准的编译器中,最好使用shrink_to_fit()函数来请求收缩内存,这是C++11引入的函数,并作为标准函数来直接缩小容器的内存空间。
七.函数接口总结

以下是一些对std::vector的扩展函数和成员类型:

函数或成员类型描述
std::vector::emplace_hint在指定位置的提示前插入元素
std::vector::insert_or_assign插入元素或修改现有元素的值
std::vector::erase移除指定位置或指定范围的元素
std::vector::erase_if根据给定的谓词函数删除元素
std::vector::remove移除指定值的所有元素
std::vector::remove_if根据给定的谓词函数删除元素
std::vector::swap交换两个向量的内容
std::vector::merge合并两个已排序的向量,并将结果存储在第一个向量中
std::vector::sort对向量的元素进行排序
std::vector::stable_sort对向量的元素进行稳定排序
std::vector::reverse反转向量中元素的顺序
std::vector::unique移除重复的元素,仅保留相邻的一个
std::vector::unique根据给定的谓词函数移除重复的元素
std::vector::binary_search使用二分查找在排序的向量中查找元素
std::vector::lower_bound返回一个迭代器,指向在已排序向量中首次出现不小于给定值的元素位置
std::vector::upper_bound返回一个迭代器,指向在已排序向量中首次出现大于给定值的元素位置
std::vector::equal_range返回一个pair,其中第一个迭代器是lower_bound返回值,第二个迭代器是upper_bound返回值
std::vector::rbegin返回指向最后一个元素的反向迭代器
std::vector::rend返回指向第一个元素之前位置的反向迭代器
std::vector::cbegin返回指向第一个元素的常量迭代器
std::vector::cend返回指向最后一个元素之后位置的常量迭代器
std::vector::crbegin返回指向最后一个元素的反向常量迭代器
std::vector::crend返回指向第一个元素之前位置的反向常量迭代器
std::vector::max_size返回向量能容纳的最大元素数量
std::vector::reserve提前预留指定的容量,以减少重新分配内存的次数
std::vector::emplace_hint在指定位置的提示前插入元素
std::vector::insert_or_assign插入元素或修改现有元素的值
std::vector::get_allocator返回与向量关联的内存分配器
std::vector::operator==判断两个向量是否相等
std::vector::operator!=判断两个向量是否不相等
std::vector::operator<比较两个向量的字典序
std::vector::operator<=判断一个向量是否小于等于另一个向量
std::vector::operator>判断一个向量是否大于另一个向量
std::vector::operator>=判断一个向量是否大于等于另一个向量
std::vector::emplace_hint在指定位置的提示前插入元素
std::vector::insert_or_assign插入元素或修改现有元素的值
std::vector::erase移除指定位置或指定范围的元素
std::vector::erase_if根据给定的谓词函数删除元素
std::vector::remove移除指定值的所有元素
std::vector::remove_if根据给定的谓词函数删除元素
std::vector::swap交换两个向量的内容
std::vector::merge合并两个已排序的向量,并将结果存储在第一个向量中
std::vector::sort对向量的元素进行排序
std::vector::stable_sort对向量的元素进行稳定排序
std::vector::reverse反转向量中元素的顺序
std::vector::unique移除重复的元素,仅保留相邻的一个
std::vector::unique根据给定的谓词函数移除重复的元素
std::vector::binary_search使用二分查找在排序的向量中查找元素
std::vector::lower_bound返回一个迭代器,指向在已排序向量中首次出现不小于给定值的元素位置
std::vector::upper_bound返回一个迭代器,指向在已排序向量中首次出现大于给定值的元素位置
std::vector::equal_range返回一个pair,其中第一个迭代器是lower_bound返回值,第二个迭代器是upper_bound返回值

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

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

相关文章

第27章_瑞萨MCU零基础入门系列教程之freeRTOS实验

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

Anaconda下Jupyter Notebook执行OpenCV中cv2.imshow()报错(错误码为1272)网上解法汇总记录和最终处理方式

零、我设备的相关信息 Python 3.8.8Anaconda3 2021.05查询匹配python3.8.*的OpenCV匹配版本为&#xff1a;4.1.* — 4.2.*&#xff0c;我最后安装4.2.0.32版本如下我记录了 “从发现问题&#xff0c;到不断试错&#xff0c;最后解决问题” 的完整过程&#xff0c;以备自己复盘…

二叉树顺序存储结构

目录 1.二叉树顺序存储结构 2.堆的概念及结构 3.堆的相关接口实现 3.1 堆的插入及向上调整算法 3.1.1 向上调整算法 3.1.2 堆的插入 3.2 堆的删除及向下调整算法 3.2.1 向下调整算法 3.2.2 堆的删除 3.3 其它接口和代码实现 4.建堆或数组调堆的两种方式及复杂度分析…

SpringCloud Eureka搭建会员中心服务提供方-集群

&#x1f600;前言 本篇博文是关于SpringCloud Eureka搭建会员中心服务提供方-集群&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您…

【Transformer系列】深入浅出理解Attention和Self-Attention机制

一、参考资料 课件&#xff1a;10_Transformer_1.pdf 视频&#xff1a;Transformer模型(1/2): 剥离RNN&#xff0c;保留Attention 二、Attention without RNN Attention模型可以看到全局的信息。 本章节以 Seq2Seq&#xff08; (encoder decoder)&#xff09; 模型为例&…

算法通关18关 | 回溯模板如何解决复原IP问题

18关的前几篇文章看过之后&#xff0c;对回溯的模板问题基本解题思路就知道了&#xff0c;就是固定的for循环问题&#xff0c;外层for循环控制横向&#xff0c;递归控制纵向&#xff0c;还要考虑撤销操作和元素是否能被重复利用问题&#xff0c;重复利用的情景较少&#xff0c;…

【物联网】简要解释RTK(Real-Time Kinematic)>>实时动态差分定位

引言&#xff1a; RTK&#xff08;Real-Time Kinematic&#xff09;技术是一种基于差分GPS的高精度定位技术&#xff0c;它通过实时通信和数据处理&#xff0c;能够提供厘米级甚至亚米级的定位精度。RTK技术在许多领域都得到了广泛应用&#xff0c;如测绘、航空航天、农业等。本…

C++ 内存模型 Memory Model

CPU 现在CPU都是多核结构&#xff0c;每个核心都有自己的一级缓存&#xff0c;二级缓存&#xff0c;以及共享的三级缓存。如下图&#xff0c;其中一级缓存分为指令缓存IL1和数据缓存DL1&#xff0c;二级缓存L2 256kB&#xff0c;三级缓存 L3 8MB。 从上图可以看出L3比L2大得多…

从零开始:PostgreSQL入门完全指南

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

【漏洞复现】大华智慧园区综合管理平台前台任意文件上传漏洞

文章目录 前言声明一、简介二、影响范围三、资产搜索四、漏洞测试四、修复建议前言 大华智慧园区综合管理平台存在前台任意文件上传漏洞,攻击者可通过特定Payload获取服务器敏感信息,进而获取服务器控制权限。 声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用…

树和二叉树的相关概念及结构

目录 1.树的概念及结构 1.1 树的概念 1.2 树的相关概念 1.3 树的表示 1.3.1 孩子兄弟表示法 1.3.2 双亲表示法 1.4 树的实际应用 2.二叉树的概念及结构 2.1 二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.4.1 顺序存储 2.4.2 链式存储 1.树…

idea内存不足

The IDE is running low on memory and this might affect performance. Please consider increasing available heap. 参考 【IDEA】The IDE is running low on memory and this might affect performance._datagrip提示ide內存不足_Coder_贾俊浩的博客-CSDN博客 (亲测好用…

零基础教你搭建日用百货线上商城小程序

在当今的数字化时代&#xff0c;小程序商城已成为许多企业和商家的首选平台&#xff0c;尤其是日用百货行业。通过小程序商城&#xff0c;消费者可以更方便地购买各类日用品&#xff0c;商家也可以提高销售效率、扩大市场影响力。本文将详细介绍如何从零开始制作一个日用百货小…

论文解读 | MVSNet:非结构化多视图立体的深度推理

原创 | 文 BFT机器人 这篇论文的题目是《MVSNet: Depth Inference for Unstructured Multi-view Stereo》。这是一篇关于深度学习在多视角立体视觉&#xff08;MVS&#xff09;中的应用的研究论文。MVS任务的目标是从多个视角的图像中还原出三维场景的深度信息&#xff0c;从而…

佛山融资融券(两融)开户利率最低能做到多少?5%!

佛山融资融券(两融)开户利率最低能做到多少?5%! 具体佛山融资融券(两融)开户利率最低能做到多少&#xff0c;需要根据不同的券商政策而定。不同的券商可能具有不同的优惠政策和开户条件&#xff0c;因此开户前应该仔细了解券商的政策和条件。 融资融券是投资者通过证券公司向…

VScode配置Ros环境

VScode配置Ros环境 VScode配置Ros环境 1. VSCode下载 直接百度搜索VScode&#xff0c;去官网安装Ubuntu版本的VScode&#xff0c;下载完成之后用Ububtu Software进行安装。 2. VScode配置 2.1 功能包配置 下载完成之后直接打开ROS的工作目录&#xff0c;之后安装ROS包。 …

LeetCode 238. 除自身以外数组的乘积

题目链接 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目解析 使用前缀和进行解决该题&#xff0c;只不过与之前前缀和不同的是这个题目计算前缀和的时候不需要计算当前元素&#xff0c;也就是当前位置前缀和的值其实是不包含当前元素的前缀和。…

递归二进制【典中典】

洛谷 #include<iostream> #include<algorithm> using namespace std; const int N3e7; int path[N]; int n,idx;//我们使用二进制的形式来解决这个问题 //移位运算的优先级高于按位与的优先级 void dfs(int x,int st) {if(xn){path[idx]st;return;}//选----1dfs(x1…

C语言之指针进阶篇(3)

目录 思维导图 回调函数 案例1—计算器 案例2—qsort函数 关于qsort函数 演示qsort函数的使用 案例3—冒泡排序 整型数据冒泡排序 回调函数搞定各类型冒泡排序 cmp_int比较大小 cmp传参数 NO1. NO2. 解决方案 交换swap 总代码 今天我们学习指针难点之回调函数…

网站搭建从零开始(0)--域名的选择与解析

目录 确定用途 购买域名 使用可靠的注册商购买域名 想好域名关键词 检查域名是否可用 添加域名到购物车并完成购买 域名的解析 登录注册商账户 选择要配置的域名 进入DNS解析设置 添加DNS记录 保存配置 检查解析是否生效 提示 确定用途 在购买域名之前&#xf…