C++(std::vector)

news/2025/1/15 19:24:54/文章来源:https://www.cnblogs.com/keye/p/18401509

目录
  • 1. 特性
  • 2. 常用成员函数
    • 2.1 构造函数
    • 2.2 元素访问
    • 2.3 修改容器
    • 2.4 容量相关
    • 2.5 迭代器
  • 3. 内存管理与效率
  • 4. 示例:
  • 5. 性能分析:



std::vector 是 C++ 标准库中的一个动态数组容器,位于 #include <vector> 头文件中。它是一个模板类,可以存储任何类型的对象,并根据需要动态调整其大小。std::vector 提供了高效的随机访问、尾部插入/删除操作(O(1)),但在中间插入或删除元素的性能较差(O(n))。



1. 特性

  1. 动态大小std::vector 能自动调整大小,随着元素的增加,容量会自动扩展。
  2. 连续内存存储:由于 std::vector 的存储空间是连续的,它支持像数组一样的随机访问,时间复杂度为 O(1)。
  3. 自动管理内存std::vector 自动管理内存的分配和释放,不需要手动调用 newdelete
  4. 模板类:可以存储任意类型的对象,必须在创建 std::vector 时指定存储的对象类型,例如 std::vector<int> 存储整数,std::vector<std::string> 存储字符串。
  5. 支持范围检查:通过 at() 方法访问元素时会进行范围检查,如果索引越界会抛出 std::out_of_range 异常,而使用 operator[] 则不会进行检查。


2. 常用成员函数

2.1 构造函数

  • std::vector<T> v;:创建一个空的向量。
  • std::vector<T> v(n);:创建一个包含 n 个默认值为 T() 的元素的向量。
  • std::vector<T> v(n, value);:创建一个包含 n 个值为 value 的元素的向量。
  • std::vector<T> v{elements...};:通过初始化列表来初始化 std::vector

2.2 元素访问

  • v[i]:返回向量中第 i 个元素(不进行边界检查)。
  • v.at(i):返回向量中第 i 个元素(进行边界检查)。
  • v.front():返回第一个元素。
  • v.back():返回最后一个元素。
  • v.data():返回指向存储数组的指针。

2.3 修改容器

  • v.push_back(value):在向量的末尾添加元素 value
  • v.pop_back():删除向量中的最后一个元素。
  • v.insert(iterator, value):在指定位置插入元素。
  • v.erase(iterator):删除指定位置的元素。
  • v.clear():删除所有元素,使向量为空。
  • v.resize(n):调整向量大小为 n,若 n 大于当前大小,增加的元素将初始化为默认值。
  • v.reserve(n):预留空间至少能容纳 n 个元素,避免多次分配内存。

2.4 容量相关

  • v.size():返回向量中当前元素的数量。
  • v.capacity():返回向量当前容量,即不重新分配内存的情况下,最多能容纳多少元素。
  • v.empty():判断向量是否为空。

2.5 迭代器

  • v.begin():返回指向第一个元素的迭代器。
  • v.end():返回指向最后一个元素之后的迭代器。
  • v.rbegin():返回指向最后一个元素的反向迭代器。
  • v.rend():返回指向第一个元素之前的反向迭代器。


3. 内存管理与效率

  • std::vector 的内存分配具有一定的增长策略,当容量不足时,会重新分配一个更大的内存块(通常是当前容量的 1.5 倍或 2 倍),并将现有元素复制到新的内存块中。这种策略可以减少多次分配和复制的开销,但也可能导致暂时的内存浪费。

  • 使用 reserve() 可以预先分配足够的空间,从而避免多次扩容带来的开销,特别是在可以预测元素数量时。

  • shrink_to_fit():这个方法请求减少容量以匹配大小,不过实现可以选择忽略此请求。它可能会将未使用的空间释放给操作系统。



4. 示例:

#include <iostream>
#include <vector>int main() {std::vector<int> v = {1, 2, 3, 4, 5};// 添加元素v.push_back(6);// 访问元素std::cout << "Element at index 2: " << v[2] << std::endl;std::cout << "First element: " << v.front() << std::endl;std::cout << "Last element: " << v.back() << std::endl;// 修改元素v[1] = 10;// 输出向量的所有元素for (int x : v) {std::cout << x << " ";}std::cout << std::endl;// 删除最后一个元素v.pop_back();// 输出当前大小和容量std::cout << "Size: " << v.size() << std::endl;std::cout << "Capacity: " << v.capacity() << std::endl;return 0;
}


5. 性能分析:

  • 时间复杂度:
    • 访问元素的时间复杂度为 O(1)。
    • 在尾部插入或删除元素的时间复杂度为摊销 O(1),因为扩展操作在多次插入后才会触发。
    • 插入或删除元素(非尾部)的时间复杂度为 O(n),因为插入或删除操作需要移动后续元素。
  • 内存重分配开销:扩展向量容量时会进行内存重分配,这时所有的元素会被复制到新的内存地址,因此在频繁插入大量元素时,提前使用 reserve() 可以提高效率。

std::vector 是 C++ 中最常用的容器之一,因其灵活的动态数组功能、优秀的性能和易用性而广受欢迎。尽管它的动态扩展会有一定的开销,但通过适当的预分配(使用 reserve())和合理的使用方式,std::vector 可以满足大多数应用场景中的性能需求。



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

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

相关文章

数学基础讲解-01

真题:易 设K法 消元的过程真题:2015 不定方程问题 必考 找到特征 解题入口 真题: 重点 没做出来一道题目,多解几次性质需要理解记忆 真题: 重点!!! 有陷阱、筛选作用 做错了 没考虑为0的情况 比较喜欢考细节 常见的坑不能约 需要移项一道题目做个三五遍不算多…

CF1945F Kirill and Mushrooms

题意 营地里的人一睡着,基里尔就偷偷溜出帐篷,去智者橡树那里采蘑菇。 众所周知,橡树下生长着 \(n\) 种蘑菇,每种蘑菇都有 \(v_i\) 的魔力。基里尔非常想用这些蘑菇制作一种魔力最大的灵药。 灵药的强度等于其中蘑菇的数量与这些蘑菇中最小魔力的乘积。为了配制灵药,基里尔…

我发布了一款相亲平台《i相遇》

因缘际会之下,我踏入了相亲平台的领域。起初,是为一位客户打造专属相亲应用,过程中深入体验了众多同类平台,却遗憾地发现它们普遍掺杂着欺诈的阴影——高昂的费用、兼职托儿的身影、以及虚假的钓鱼信息,不一而足。 完成客户项目后,我决定自己运营一款专为互联网人量身打造…

Linux系统安装ansiblle环境

前言:这里是生产环境红帽系统,如果是别的系统,本地源的配置方法不一样。 一、主节点服务器Redhat8 配置使用阿里源: 备份:sudo /etc/yum.repos.d/CentOS-Base.repo /opt/yum/ 下载新的CentOS-Base.repo 到 /etc/yum.repos.d/ (这里用的CentOS 8.0) 命令:sudo wget -O /…

1.hadoop入门

Hadoop入门一.概念1.hadoop是什么 (1)Hadoop是一个由apache基金会所开发的分布式系统基础架构(2)主要解决,海量数据的存储和海量数据的分析计算问题(3)广义上来说,hadoop通常是指一个更广泛的概念--hadoop生态圈2.Hadoop发展历史(1)创始人Doug Cutting,为了实现与Google类似的全…

JQuery的DOM操作

JQuery基础教程第四版第五章:DOM操作方法的简单归纳 使用JQuery的DOM操作实现以下功能1.创建新元素2.插入新元素3.移动元素4.包装元素5.复制元素 相关代码 HTML文件<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"&g…

C++顺序结构(1)

1、C++程序的样子2、流 输出流 COUT<<3、一个实例及解析 // 001 程序的基本结构 //单行注释 /*多行注释 被注释过的内容不会被运行,可以用来做笔记。 基本结构: 1.头文件 程序包含某个头文件后,程序中的代码就可以使用这个头文件里的功能。 2.命名空间 3.主函数 类…

manim边学边做--角度标记

manim中绘制一个角度其实就是绘制两条直线,本篇介绍的不是绘制角度,而是绘制角度标记。 对于锐角和钝角,角度标记是一个弧,弧的度数与角的度数一样; 对于直角,角度标记是一个垂直的拐角。 manim中关于角度标记的模型主要有3个:Angle:根据两条直线绘制角度标记 RightAng…

关于Tailscale Subnet routers要说的

国内的水文很多,Tailscale的部署就不说了。简单的都有讲到,但凡深度一点儿的只能找找外边儿的文章了。 昨天刚给群晖装完Tailscale,打算着利用Subnet routers功能来访问另外的2个子网。 国内的水文在介绍这一段使用的时候是这样的:该文章提到:如果有多个网段添加,就多运行…

CASIA-OLHWDB1.0-1.2数据集解析

OLHWDB1.0-1.2提供联机手写单字数据。 OLHWDB1.0收录汉字3866个,字母数字及符号171个。其中,GB2312-80一级集(共3755个字符)收录汉字3740个。 OLHWDB1.1收录GB2312-80一级集汉字3755个,字母数字及符号171个。 OLHWDB1.2收录汉字3319个,字母数字及符号171个。OLHWDB1.2的汉…

枚举测试

/*** 枚举类*/ public enum SocialTypeEnum {FACEBOOK(1),//脸书GITEE(2),//GITEEWECHAT_ENTERPRISE(3);//企业微信 <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">final</span> <span style=&…

ROS话题通信

# 发布方 # 以发布订阅的方式实现不同节点之间数据交互的通讯模式,用于不断更新的、少逻辑处理的数据传输场景 impoosyt rospy from std_msgs.msg import String# 初始化ROS节点(命门) rospy.init_node("talker_1") # 实例化发布者对象 pub_1 = rospy.Publisher(&…