C++ STL 详解 ——vector 的深度解析与实践指南

一、vector 的核心概念与底层机制

1.1 动态数组的本质

  • 连续内存存储:与普通数组相同,vector 使用连续的内存空间,支持 O (1) 时间复杂度的随机访问。
  • 动态扩容特性:通过push_back等操作自动调整容量,无需手动管理内存。
  • 与数组的区别
    特性普通数组vector
    内存分配静态分配动态分配
    大小可变
    越界检查无(需手动检查)
    内存管理手动释放自动管理

 

1.2 扩容策略的深度解析

  • 常见扩容方式
    • 指数增长:每次扩容为当前容量的 2 倍(如 GCC STL)。
    • 线性增长:每次扩容固定增量(如 MSVC STL)。
  • 示例代码
    vector<int> v;
    for (int i = 0; i < 10; ++i) {v.push_back(i);cout << "Size: " << v.size() << " Capacity: " << v.capacity() << endl;
    }
    
  • 输出结果(以 GCC 为例):
    Size: 1 Capacity: 1
    Size: 2 Capacity: 2
    Size: 3 Capacity: 4
    ...
    

二、vector 的基础用法与高级操作

2.1 初始化方式的全面总结

方式示例代码说明
空容器vector<int> v1;初始容量为 0
指定大小与初始值vector<int> v2(10, 2);10 个元素,值为 2
拷贝构造vector<int> v3(v2);复制 v2 的内容
迭代器范围构造vector<int> v4(v2.begin(), v2.end());复制区间 [begin, end) 的元素
其他容器转换vector<char> v5(s.begin(), s.end());将 string 转换为 vector

2.2 空间管理函数的对比

函数作用复杂度示例代码
size()返回有效元素个数O(1)cout << v.size();
capacity()返回当前分配的最大容量O(1)cout << v.capacity();
reserve(n)预留至少 n 个元素的空间O(n)v.reserve(100);
resize(n)调整元素个数为 n,新元素默认值为 0O(n)v.resize(5);
empty()判断容器是否为空O(1)if (v.empty()) ...

2.3 迭代器的高级应用

  • 迭代器类型
    • 正向迭代器vector<int>::iterator
    • 反向迭代器vector<int>::reverse_iterator
    • 常量迭代器vector<int>::const_iterator
  • 遍历方式对比
    // 下标遍历
    for (size_t i = 0; i < v.size(); ++i) { /* ... */ }// 正向迭代器遍历
    for (auto it = v.begin(); it != v.end(); ++it) { /* ... */ }// 反向迭代器遍历
    for (auto rit = v.rbegin(); rit != v.rend(); ++rit) { /* ... */ }// 范围for循环
    for (auto& element : v) { /* ... */ }
    

三、增删查改操作的最佳实践

3.1 插入操作的性能优化

  • 尾插push_back()时间复杂度为 O (1)(均摊)。
  • 任意位置插入insert(pos, val)时间复杂度为 O (n)(需移动元素)。
  • 批量插入
    // 插入多个相同元素
    v.insert(v.begin(), 5, -1); // 在开头插入5个-1// 插入其他容器元素
    vector<int> src = {1, 2, 3};
    v.insert(v.end(), src.begin(), src.end());
    

3.2 删除操作的注意事项

  • 尾删pop_back()时间复杂度为 O (1)。
  • 任意位置删除erase(pos)时间复杂度为 O (n)。
  • 按值删除:结合find()erase()
    auto pos = find(v.begin(), v.end(), 2);
    if (pos != v.end()) {v.erase(pos);
    }
    

3.3 元素访问的安全方式

  • 使用at()代替[]
    try {cout << v.at(5); // 越界时抛出out_of_range异常
    } catch (const exception& e) {cerr << e.what() << endl;
    }
    

四、迭代器失效问题与解决方案

4.1 失效场景分析

操作类型迭代器失效原因影响范围
插入元素可能导致扩容,所有迭代器失效全部迭代器
删除元素被删除元素之后的迭代器失效删除点之后的迭代器
resize()若容量变化,所有迭代器失效全部迭代器(若容量变化)

4.2 经典案例与修复方案

案例 1:插入后删除导致的失效

// 错误代码
auto pos = find(v.begin(), v.end(), 2);
v.insert(pos, 10); // 插入后pos失效
v.erase(pos);      // 非法访问// 正确代码
auto pos = find(v.begin(), v.end(), 2);
v.insert(pos, 10);
pos = find(v.begin(), v.end(), 2); // 重新获取pos
v.erase(pos);

案例 2:遍历删除偶数时的越界

// 错误代码
for (auto it = v.begin(); it != v.end(); ++it) {if (*it % 2 == 0) {v.erase(it); // it失效后继续递增}
}// 正确代码
for (auto it = v.begin(); it != v.end(); ) {if (*it % 2 == 0) {it = v.erase(it); // erase返回下一个有效迭代器} else {++it;}
}

五、vector 的性能优化与最佳实践

5.1 预分配空间

  • 场景:已知需要存储大量元素时,使用reserve()减少扩容次数。
  • 示例
    vector<int> v;
    v.reserve(1000); // 预分配1000个元素空间
    for (int i = 0; i < 1000; ++i) {v.push_back(i); // 无扩容开销
    }
    

5.2 避免不必要的拷贝

  • 使用移动语义
    vector<string> vs;
    vs.push_back("hello"); // 深拷贝
    vs.push_back(move("world")); // 移动语义,避免拷贝
    

5.3 与其他容器的选择对比

容器随机访问插入 / 删除(非尾部)内存占用适用场景
vectorO(1)O(n)较小动态数组、频繁随机访问
listO(n)O(1)较大频繁插入 / 删除
dequeO(1)O (1)(首尾)中等双端队列操作

六、常见问题与解答

6.1 为什么 vector 的 capacity 总是大于等于 size?

  • 原因:vector 会预分配额外空间以优化插入操作的性能。

6.2 如何释放 vector 的多余内存?

  • 方法:使用swap技巧:
    vector<int>().swap(v); // 临时vector与v交换,释放内存
    

6.3 vector<bool>的特殊性

  • 注意vector<bool>并非存储bool类型,而是特化为bitset以节省空间,迭代器行为可能不同。

七、扩展资源与推荐阅读

  1. C++ 官方文档:vector
  2. 《C++ Primer》:第 9 章 顺序容器
  3. Stack Overflow 专题:vector 扩容策略

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

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

相关文章

【SpringBoot】——在做一些项目中所学到的新的技术栈和一些小技巧(主要为MQ,详细请看目录和文章)

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大三学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

0经验cursor开发一款跨端app

设备&#xff1a;mac电脑cursor 1.输入诉求 我要实现一个跨端的地址应用&#xff0c;使其可以在ios、安卓、小程序和网页端都可以使用。这是一个demo的项目&#xff0c;功能不必要太过复杂&#xff0c;下面需要你和我多次沟通完成这个任务。你先根据我的内容输入&#xff0c…

Element Ui - 编辑时表单校验信息未清空问题处理

Element Ui 关闭对话框清空验证消息&#xff0c;清除form表单的操作 首先在对话框 取消按钮 添加 click事件&#xff0c;例如&#xff1a;&#xff08;ps&#xff1a;callOf 里面的addGroupData和ref - - &#xff09; <div slot"footer" class"dialog-foo…

OpenCV图像加权函数:addWeighted

1 addWeighted函数 在OpenCV 里&#xff0c;addWeighted 函数的作用是对两个图像进行加权求和&#xff0c;常用于图像融合、图像过渡等场景。函数如下&#xff1a; cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])2 参数解释 src1&#xff1a;第一个输入图…

Science Robotics 利用机器学习进行鳐鱼的仿生设计

对于海洋生物而言&#xff0c;生物力学和流体动力学力都会对游泳速度施加物理限制&#xff0c;促使游泳策略和鳍形状的趋同进化。鉴于这些限制是与尺度相关的&#xff0c;如雷诺数&#xff08;Re&#xff09;&#xff0c;这就产生了自然运动缩放定律&#xff0c;该定律根据生物…

基于ssm的一家运动鞋店的产品推广网站的设计

项目简介 一家运动鞋店实现了以下功能&#xff1a; 实现了用户在线选择试题并完成答题&#xff0c;在线查看考核分数。管理员管理收货地址管理、购物车管理、字典管理、留言版管理、新闻信息管理、产品管理、产品收藏管理、产品评价管理、产品订单管理、单页数据管理、用户管…

什么是后训练?大语言模型训练后优化方法综述,87页pdf

大语言模型&#xff08;LLMs&#xff09;的出现彻底改变了自然语言处理领域&#xff0c;使其在从对话系统到科学探索的各个领域中变得不可或缺。然而&#xff0c;其预训练架构在特定场景中往往表现出局限性&#xff0c;包括推理能力受限、伦理不确定性以及领域特定性能欠佳等问…

python开发订单查询功能(flask+orm bee)

1. 搭建python环境。 可以参考其它文档。 此处python使用 3.12 IDE随意&#xff0c;PyCharm 或 Eclipse PyDev也可以。 2. Flask 2.1 安装Flask pip install Flask 2.2 一个最简单的flask实例 创建一个工程&#xff0c; 新建一个 main.py文件&#xff0c; 输入以下内容…

工作记录 2017-01-11

工作记录 2017-01-11 序号 工作 相关人员 1 协助BPO进行Billing的工作。 修改邮件上的问题。 更新RD服务器。 郝 更新的问题 1、修改了Patient Insurance的文件上传。 1.1 文件存储改为MedI“EHRWfs”Account“patientInfo”MRN 1.2 “Upload Files” to “Upload/Vie…

基于javaweb的SpringBoot个人健康管理系统小程序微信小程序设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

b站视频下载工具软件怎么下载

自行配置FFMPEG环境 请优先选择批量下载&#xff0c;会自处理视频和音频文件。 如果要下载更高质量请登陆。 没有配置FFMPEG下载后会有报错提示&#xff0c;视频音频文件无法合并生成mp4文件 更新批量下载标题&#xff0c;只取视频原标题&#xff0c;B站反爬机制登陆后下载多了…

简单的模拟法

1. 鸡兔同笼问题&#xff0c;鸡有2只脚 &#xff0c;兔有4只脚&#xff0c;已知脚数求最多有几只动物 #include <stdio.h>void feet(int x){if(x%2 0){if(x%4 0) printf("max%d,min%d",x/2,x/4);else printf("max%d,min%d",x/2,(x-2)/41);}else …

【python爬虫】酷狗音乐爬取练习

注意&#xff1a;本次爬取的音乐仅有1分钟试听&#xff0c;仅作学习爬虫的原理&#xff0c;完整音乐需要自行下载客户端。 一、 初步分析 登陆酷狗音乐后随机选取一首歌&#xff0c;在请求里发现一段mp3文件&#xff0c;复制网址&#xff0c;确实是我们需要的url。 复制音频的…

概率论的基本知识

逆概率还不懂&#xff0c;改天再想想。 联合概率 联合概率&#xff08;Joint Probability&#xff09; 是概率论中的一个重要概念&#xff0c;用于描述多个随机变量同时取某些值的概率。联合概率可以帮助我们理解多个变量之间的关系。

Ceph(1):分布式存储技术简介

1 分布式存储技术简介 1.1 分布式存储系统的特性 &#xff08;1&#xff09;可扩展 分布式存储系统可以扩展到几百台甚至几千台的集群规模&#xff0c;而且随着集群规模的增长&#xff0c;系统整体性能表现为线性增长。分布式存储的水平扩展有以下几个特性&#xff1a; 节点…

Pytest自动化测试框架pytest-xdist分布式测试插件

平常我们功能测试用例非常多时&#xff0c;比如有1千条用例&#xff0c;假设每个用例执行需要1分钟&#xff0c;如果单个测试人员执行需要1000分钟才能跑完&#xff1b; 当项目非常紧急时&#xff0c;会需要协调多个测试资源来把任务分成两部分&#xff0c;于是执行时间缩短一…

在openEuler-22.03-LTS上利用Ansible轻松部署MySQL 5.7

一、需求 使用ansible自动化部署mysql二进制部署mysql部署mysql并创建JDBC用户 二、环境信息 本文涉及的代码&#xff0c;配置文件地址&#xff1a; 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;1g6y 软件名称版本备注Ansible2.9.27All modules — Ansible Doc…

使用GitHub Actions实现Git推送自动部署到服务器

将网站一键部署到服务器的方案很多&#xff0c;比如纯Shell脚本结合SSH、Jenkins等工具。本文将介绍如何利用GitHub Actions这一免费且轻量的CI/CD工具&#xff0c;实现代码推送后自动部署到云服务器。 之前一直在使用github的工作流&#xff0c;确实是一个比较好用的工具。 我…

网络安全 与 加密算法

计算机中的网络安全 在本篇中介绍了以下几个方面: 机密性 密码学 对称加密算法(DES, 3DES, AES) 公开秘钥算法 RSA大素数的获取 完整性 散列函数(MD5, SHA-1, 并没有提及算法实现) 报文鉴别(MAC) 数字签名 端点鉴别 应用 SSL(TCP网络安全) 运行时安全 防火墙的基本知…

DeepSeek-prompt指令-当DeepSeek答非所问,应该如何准确的表达我们的诉求?

当DeepSeek答非所问&#xff0c;应该如何准确的表达我们的诉求&#xff1f;不同使用场景如何向DeepSeek发问&#xff1f;是否有指令公式&#xff1f; 目录 1、 扮演专家型指令2、 知识蒸馏型指令3、 颗粒度调节型指令4、 时间轴推演型指令5、 极端测试型6、 逆向思维型指令7、…