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

相关推荐

  • 在使用 VS Code 和 Keil 协同开发 STM32 程序

    在使用 VS Code 和 Keil 协同开发 STM32 程序时,可以利用 Keil 强大的编译器 和 VS Code 的高效代码编辑功能,结合起来提高开发效率。以下是实现协同开发的详细步骤: 前置准备安装 Keil确保已安装 Keil MDK-ARM,并配置好开发环境。Keil 下载地址:Keil 官方网站安装 VS Code下载并安装最新版本的 VS …

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

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

    2024年11月24日
    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
  • 若依集成 X-File-Storage 框架(实现图片上传阿里云 OSS 服务器)

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

    2024年11月25日
    00
  • 在 Windows 上使用 PyCharm 进行远程开发并连接到 Spark 进行 PySpark 开发

    在 Windows 上使用 PyCharm 进行远程开发并连接到 Spark 进行 PySpark 开发,通常涉及以下几个步骤:1. 设置 PyCharm 环境首先,需要安装 PyCharm,并确保你使用的是专业版(Professional),因为它支持远程开发。确保 Python 已经安装,并配置好虚拟环境。2. 配置远程开发环境在 Windows 上使用…

    2024年11月27日
    00
  • 安装 Laravel 11 + Filament 详细教程

    安装Laravel 11之前选确保安装了Composer 管理器,接下来的步骤是通过Composer 包管理器安装完成的。 一、前提条件 二、使用 Composer 创建新的 Laravel 11 项目 三、在现有项目中添加 Laravel 11(如果是集成到现有项目) 请注意,在实际安装过程中,可能会遇到各种问题,如权限问题(在 Linux 下,如果没有足…

    2025年1月18日
    00
  • 在 WPF 中使用 Vlc.DotNet 和 LibVLCSharp.WPF 两种库来进行 VLC 的二次开发

    在 WPF 中使用 Vlc.DotNet 和 LibVLCSharp.WPF 两种库来进行 VLC 的二次开发,可以实现丰富的视频播放功能,比如播放本地视频、流媒体、控制播放、获取视频信息等功能。以下是对两者的介绍及开发步骤。 一、Vlc.DotNet 和 LibVLCSharp 的对比 特性 Vlc.DotNet LibVLCSharp.WPF 开发活跃度…

    2024年12月3日
    00
  • uni-app 中的一个 API,uni.getLocation用于获取用户的地理位置信息

    uni.getLocation 是 uni-app 中的一个 API,用于获取用户的地理位置信息。它可以通过 GPS 或网络方式获取当前位置,并提供包括经纬度、速度、精度等信息。这个 API 在移动端(如安卓、iOS)和 H5 平台上均可使用。基本语法 参数说明type(可选):指定位置的坐标类型。支持 ‘wgs84’ 和 ‘gcj02’,默认值为 ‘wgs…

    2024年11月28日
    00
  • 在 Spring Boot 中实现定时任务,通过 Spring Task Scheduling 来完成

    在 Spring Boot 中实现定时任务,可以通过 Spring Task Scheduling 来轻松完成。Spring 提供了多种方法来调度任务,其中使用 @Scheduled 注解是最常见且简单的方式。 步骤:在 Spring Boot 中实现定时任务 1. 启用定时任务 首先,确保在 Spring Boot 应用的主类或配置类中启用定时任务功能: …

    2024年11月26日
    00
  • 搭建一个基于 Node.js 和 MySQL 的微信小程序

    搭建一个基于 Node.js 和 MySQL 的微信小程序后台可以帮助你管理数据、处理请求、存储用户信息等。下面是如何从头开始搭建一个基本的微信小程序后台系统的详细步骤。 1. 环境准备 确保你已经安装以下开发工具: 2. 创建 Node.js 项目 首先,创建一个新的 Node.js 项目: 2. 安装必要的依赖包: 使用以下命令安装这些依赖: 配置 My…

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

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

    2024年11月25日
    00
  • 在 Linux 系统上配置 Hadoop 环境,包括创建 hadoop 用户、更新 apt、安装 SSH 和配置 Java 环境

    以下是详细的步骤,用于在 Linux 系统上配置 Hadoop 环境,包括创建 hadoop 用户、更新 apt、安装 SSH 和配置 Java 环境。 1. 创建 Hadoop 用户创建一个名为 hadoop 的新用户: 根据提示设置密码和用户信息。 将 hadoop 用户添加到 sudo 组(可选): 切换到 hadoop 用户: 2. 更新 APT 包…

    2024年12月1日
    00
  • 出现 ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES) 错误的解决方法

    出现 ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES) 错误,通常是由于 MySQL 用户身份验证失败,可能的原因包括密码错误、用户权限配置问题或身份验证插件不匹配等。以下是解决方法: 1. 检查密码是否正确确保输入的密码与 MySQL 中为…

    2024年11月26日
    00
  • 将FFmpeg集成到 Spring Cloud构建分布式系统 对视频压缩处理

    在使用Spring Cloud构建分布式系统时,可以将FFmpeg集成到其中,用于对视频进行压缩和处理。以下是一个实现示例的详细步骤,包括代码示例和配置说明。 1. FFmpeg 简介 FFmpeg 是一个强大的开源工具,可以用来对音视频进行转换、压缩、剪辑等操作。通过命令行工具或调用其库,你可以高效处理多种格式的视频。 2. 环境准备 安装 FFmpeg …

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

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

    2024年11月26日
    00

发表回复

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

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信