C++ STL vector 类:动态数组的高效应用

vectorC++ 标准库(STL)中最常用的容器之一,它提供了一个动态数组的实现,能够根据需要自动扩展或收缩。vector 是一个线性数据结构,具有高效的随机访问能力和动态扩展能力,广泛应用于需要频繁增删元素且对随机访问要求较高的场景。

1. vector 类简介

vector 是 C++ 标准模板库(STL)中提供的一种容器类,它类似于动态数组(dynamic array)。不同于普通的数组,vector 可以在运行时动态调整大小,因此它适合处理元素数量未知、需要灵活增减的场景。

基本特点:

  • 动态大小vector 会根据元素的增加或减少自动调整大小。
  • 随机访问:支持通过下标快速访问元素,类似于数组,具有常数时间复杂度 O(1)。
  • 内存连续性:与数组类似,vector 内部存储的数据是连续的,因此其元素存储在内存中是一个连续的块,这也让它能够高效地访问元素。
  • 元素添加和删除:可以在末尾高效地插入元素,也支持在其他位置插入或删除,但这些操作的时间复杂度可能较高。

2. vector 的基本操作

创建 vector 对象

#include <iostream>
#include <vector>

int main() {
    // 创建一个空的 vector
    std::vector<int> vec;

    // 创建一个大小为 5 的 vector,初始化为 0
    std::vector<int> vec2(5, 0);

    // 创建一个初始化值的 vector
    std::vector<int> vec3 = {1, 2, 3, 4, 5};
    
    // 创建一个同类型的 vector,并拷贝另一个 vector
    std::vector<int> vec4(vec3);

    return 0;
}

访问元素

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 使用下标访问元素
    std::cout << "Element at index 2: " << vec[2] << std::endl;

    // 使用 at() 函数访问元素(会进行边界检查)
    std::cout << "Element at index 2: " << vec.at(2) << std::endl;

    // 获取第一个和最后一个元素
    std::cout << "First element: " << vec.front() << std::endl;
    std::cout << "Last element: " << vec.back() << std::endl;

    return 0;
}

添加和删除元素

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};

    // 添加元素到末尾
    vec.push_back(4);
    vec.push_back(5);

    // 删除末尾元素
    vec.pop_back();

    // 插入元素到指定位置
    vec.insert(vec.begin() + 1, 6);  // 在第二个位置插入 6

    // 删除指定位置的元素
    vec.erase(vec.begin() + 2);  // 删除第三个元素

    // 清空 vector
    vec.clear();

    return 0;
}

获取容量和大小

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    std::cout << "Size of vector: " << vec.size() << std::endl;
    std::cout << "Capacity of vector: " << vec.capacity() << std::endl;
    std::cout << "Is vector empty? " << (vec.empty() ? "Yes" : "No") << std::endl;

    return 0;
}
  • size():返回当前 vector 中的元素个数。
  • capacity():返回 vector 当前可以容纳的最大元素数量。
  • empty():判断 vector 是否为空。

迭代器操作

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 使用迭代器遍历 vector
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

其他常用方法

  • resize(n):改变 vector 的大小,如果新大小比当前大小大,新的元素会被默认初始化;如果小,则丢弃超出部分。
  • shrink_to_fit():请求减少容量到适合大小,释放未使用的内存。
  • swap(other):交换两个 vector 的内容。
#include <iostream>
#include <vector>

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

    // 交换 vec1 和 vec2 的内容
    vec1.swap(vec2);

    for (int num : vec1) {
        std::cout << num << " ";  // 输出 4 5 6
    }
    std::cout << std::endl;

    return 0;
}

3. vector 的优缺点

优点:

  • 快速随机访问:可以通过下标直接访问元素,时间复杂度为 O(1)。
  • 动态扩展:当容器容量不足时,vector 会自动扩展,可以容纳更多的元素。
  • 内存连续性vector 内部存储的数据是连续的,这对于缓存友好性和数据的快速访问有很大的好处。

缺点:

  • 插入和删除元素的性能差:在 vector 的开头或中间插入和删除元素时,会导致大量的元素移动,因此这些操作的时间复杂度为 O(n)。
  • 内存重分配:当 vector 超过当前容量时,会重新分配更大的内存块并复制数据,可能会造成性能开销。

4. 总结

vector 是 C++ STL 中非常强大的一个容器类,它提供了动态数组的高效实现,支持高效的随机访问和动态扩展。对于需要频繁插入、删除元素的场景,虽然 vector 在末尾操作表现出色,但如果在中间或前面插入、删除数据时,性能会有所下降。通过合理地选择容器和操作方式,可以大大提高程序的性能。

发布者:myrgd,转载请注明出处:https://www.object-c.cn/4558

Like (0)
Previous 2024年11月25日 下午8:28
Next 2024年11月26日 上午10:51

相关推荐

  • 理解 HTML、HTML5 和 “H5” 区别的重要性

    HTML & HTML5 & H5 的区别在构建现代网页时,理解 HTML、HTML5 和 “H5” 的区别是非常重要的。以下是它们的概念和主要区别: 1. HTML(超文本标记语言)定义HTML 是 HyperText Markup Language 的缩写,即超文本标记语言,用于定义网页内容的结构和含义。特性提供基…

    2024年12月2日
    00
  • 使用 CLion 编写 C51 (即8051微控制器) 程序时,遇到 sbit 相关报错

    在使用 CLion 编写 C51 (即8051微控制器) 程序时,遇到 sbit 相关报错,通常是因为 CLion 默认并不支持8051的特殊语法和寄存器定义方式。sbit 是 C51 编译器中的一个关键字,用来将一个单独的位(bit)映射到特定的硬件寄存器或端口引脚。常见的报错及解决方法sbit 语法问题: CLion 本身不支持 C51 特有的语法,sb…

    2024年11月27日
    00
  • Docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像方法

    使用 Docker 快速部署 Nginx、Redis、MySQL、Tomcat 以及制作镜像 通过 Docker,开发者可以快速部署和管理各种服务。本文介绍如何快速使用 Docker 部署 Nginx、Redis、MySQL 和 Tomcat,以及如何制作自定义镜像。 1. Docker 基础准备 安装 Docker 如果还未安装 Docker,可按照以下步…

    2024年11月26日
    00
  • 使用 Python Selenium 控制 Chrome 浏览器 进行自动化操作

    使用 Python Selenium 控制 Chrome 浏览器 进行自动化操作是 Web 自动化测试和爬虫的常用方法之一。以下是一个完整的入门教程,包括如何安装、配置以及一些示例代码。 1. 安装所需环境 1.1 安装 Selenium 使用 pip 安装 Selenium: 1.2 下载 ChromeDriver 1.3 配置 ChromeDriver …

    2024年11月25日
    00
  • 不同版本ffmpeg压缩比差距很大的问题(使用videotoolbox硬编码)

    不同版本的 FFmpeg 在使用 videotoolbox 硬件编码时,压缩比差距较大的问题,通常与以下几个因素相关:1. FFmpeg 硬件编码支持的变化:FFmpeg 集成了多种硬件加速技术(例如在 macOS 上使用 videotoolbox),而随着版本的更新,FFmpeg 可能对硬件编码进行了修复、改进或修改,这些变化可能会导致不同版本之间的压缩效…

    2024年11月27日
    00
  • 在 Spring Boot 中实现定时任务,可以使用以下三种方式

    1. 使用 @Scheduled 注解 这是 Spring 提供的简单方式,基于注解实现定时任务。 步骤: 3. 创建任务类使用 @Scheduled 注解定义定时任务: 4. @Scheduled 参数详解 2. 使用 ScheduledExecutorService 如果任务管理需要更灵活,可以使用 Java 自带的线程池。 示例: 3. 使用 Quar…

    2024年11月26日
    00
  • Python 的 json模块序列化数据从文件里读取出来或存入文件

    Python 的 json 模块用于处理 JSON 格式的数据,可以将 JSON 数据与 Python 数据结构之间相互转换。以下是具体用法,包括从文件读取 JSON 数据以及将数据写入文件: 1. 将 JSON 数据从文件中读取到 Python 数据结构 代码示例: 解析过程: 2. 将 Python 数据结构写入到文件中(序列化为 JSON) 代码示例:…

    2024年11月26日
    00
  • 远程仓库 ,从GitHub拉取代码失败的解决办法

    从GitHub拉取代码失败通常由以下几种原因引起:网络问题、认证失败、远程仓库配置错误等。以下是常见的失败场景及解决办法。 1. 网络问题症状连接超时。报错如:fatal: unable to access ‘https://github.com/…’: Failed to connect to github.com port 443: Connecti…

    2024年11月28日
    00
  • Spring Boot 项目中对接海康摄像头的视频流播放

    在 Spring Boot 项目中对接海康摄像头的视频流播放,通常需要利用摄像头的 RTSP 协议,将实时视频流解码并转发到前端以实现播放功能。以下是具体实现步骤: 1. 项目准备 前置条件 RTSP 流地址格式 海康摄像头的 RTSP 流地址格式通常为: 例如: 2. 后端实现视频流转发 为了在后端转发视频流到前端,我们需要解码 RTSP 流并将其转为适配…

    2024年11月24日
    00
  • Unity 项目升级URP/HDRP渲染管线时如何解决材质丢失问题

    在 Unity 项目中升级到 URP(通用渲染管线) 或 HDRP(高清渲染管线) 后,材质丢失是一个常见问题。这通常是因为原来的材质或着色器不兼容新渲染管线,需要手动调整或重新配置。以下是详细的解决方法: 1. 理解渲染管线的变化 2. 自动转换材质(官方工具) Unity 提供了从 Built-in 渲染管线迁移到 URP 或 HDRP 的官方工具,可以…

    2024年11月25日
    00
  • Android Studio 国内镜像,加速下载和构建过程

    在国内使用 Android Studio 时,由于访问 Google 的官方资源(如 Gradle 和 SDK)速度较慢甚至无法访问,可以通过配置国内镜像源来加速下载和构建过程。以下是详细配置步骤: 1. 配置 Gradle 国内镜像 Gradle 是 Android Studio 构建项目的重要工具,其依赖库通常托管在 Google Maven 和 JCe…

    2024年11月25日
    00
  • 微信小程序中,通过Node.js连接本地 MySQL 实现数据的增删改查

    在微信小程序中,通过Node.js连接本地 MySQL 实现数据的增删改查的过程,可以分为以下几个步骤: 1. 准备工作 必要工具: 2. 搭建 Node.js 后端服务 安装依赖 在 Node.js 项目中,使用 npm init 初始化项目,并安装以下依赖: express: 用于搭建 Web 服务。 mysql: 用于连接和操作 MySQL 数据库。 …

    2024年12月9日
    00
  • 在 Spring Boot 中实现 Callback 回调的常用方法

    在 Spring Boot 中实现 Callback(回调) 通常用于处理外部系统调用你的服务接口。例如,当一个第三方服务完成某项操作后通知你的应用完成结果。以下是实现回调的完整流程: 1. 回调的基本流程 2. 示例代码 2.1 创建回调接口 假设第三方服务会通过 POST 请求回调数据到 /callback,并发送如下 JSON 数据: 实现代码如下: …

    2024年11月24日
    00
  • Redis中如何使用lua脚本redis与lua的相互调用方法

    在 Redis 中,Lua 脚本 提供了一种强大的方式来执行原子操作,可以在 Redis 服务器上直接执行 Lua 代码,从而避免了多次网络往返和保证操作的原子性。Redis 内置了对 Lua 脚本的支持,通过 EVAL 命令来执行脚本,EVALSHA 则用于执行已经加载到 Redis 服务器的脚本。1. Redis 与 Lua 脚本的基本交互1.1 基本的…

    2024年11月28日
    00
  • 若依集成 X-File-Storage 框架(实现图片上传阿里云 OSS 服务器)

    若依(Ruoyi)是一款基于 Spring Boot 的企业级开发框架,在此框架中集成 X-File-Storage 框架来实现图片上传到阿里云 OSS(对象存储服务)是一个常见的需求。通过这个集成,你可以便捷地将图片或文件上传到阿里云 OSS,并在系统中管理和访问这些文件。以下是详细的步骤说明: 1. 安装 X-File-Storage 框架 X-File…

    2024年11月25日
    00

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信