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

相关推荐

  • 将FFmpeg集成到 Spring Cloud构建分布式系统 对视频压缩处理

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

    2024年11月23日
    00
  • 云服务器安装宝塔强制重启导致MySQL无法启动

    在云服务器上进行 强制重启 后,MySQL 无法启动的情况,通常是由于以下几种原因引起的。强制重启可能会导致 MySQL 数据库的文件系统损坏、配置文件丢失、锁定文件问题等,下面是一些排查和解决方法。1. 检查 MySQL 错误日志MySQL 无法启动时,首先需要查看 MySQL 的错误日志,以获取更多的错误信息。错误日志通常位于 /var/log/mysq…

    2024年11月29日
    00
  • Web实时通信和 @microsoft/signalr 微软开发的一款基于 SignalR 的实时通信库

    Web实时通信和 @microsoft/signalr@microsoft/signalr 是微软开发的一款基于 SignalR 的实时通信库,专为 Web 应用提供强大的实时通信功能。SignalR 的主要特点包括支持双向通信、自动选择传输协议(WebSockets、Server-Sent Events 或 Long Polling)以及简化的服务器与客户…

    2024年12月1日
    00
  • 在使用 PHP 抓取 HTTPS 资源时,会遇到一些常见问题

    在使用 PHP 抓取 HTTPS 资源时,可能会遇到一些常见问题。这些问题通常与 SSL 配置、证书验证或 PHP 设置相关。以下是常见问题及其解决方法的汇总: 1. SSL 证书验证失败问题描述当使用 file_get_contents、cURL 等方法访问 HTTPS 资源时,可能会遇到类似以下错误: 解决方法更新 cacert.pem 文件下载最新的根…

    2024年12月2日
    00
  • java中使用 Arrays.asList()新增报错问题解决方法

    Arrays.asList() 返回的是一个固定大小的列表。如果你尝试使用该列表进行添加、删除等修改操作,会抛出 UnsupportedOperationException 异常。这是因为 Arrays.asList() 返回的列表背后是一个数组,它的大小是固定的,不能进行动态修改。解决方法使用 ArrayList 包装 Arrays.asList() 的结…

    2024年12月2日
    00
  • python反爬-图像验证码与滑块验证码的跳过反selenium检测,动态ip等问题

    针对反爬措施,Python可以使用以下策略来跳过图像验证码与滑块验证码、反检测Selenium,以及通过动态IP规避限制。这是一个分步说明: 1. 图像验证码的跳过与破解1.1 图像验证码处理对于简单的图像验证码,可以使用 OCR 技术直接识别验证码内容。常用库包括:Tesseract-OCR: 一款开源 OCR 工具。Pytesseract: Tesser…

    2024年11月28日
    00
  • 在 Apache Spark 中,任务的切分(Task Division)机制

    在 Apache Spark 中,任务的切分(Task Division)是 Spark 将应用程序逻辑划分为多个并行任务的核心机制。任务切分的主要原则是基于数据分区和操作算子。以下是任务切分的核心原则和关键影响因素: 1. Spark 任务切分的基本概念 2. 任务切分的原则 2.1 基于分区(Partition)的切分 2.2 基于依赖关系(Depend…

    2024年11月25日
    00
  • wordpress 蜘蛛记录插件的功能记录网站的所有访问记录

    要在 WordPress 网站上实现类似的功能,通常你需要开发一个 WordPress 插件。以下是一步步创建一个插件的指南,它可以记录访问者的访问记录,区分搜索引擎蜘蛛,并保存访客的 IP 地址。 1. 创建插件目录和文件 2. 插件文件结构 插件的文件结构大概如下: 3. 编写插件代码 在 visitor-tracker.php 文件中,添加以下代码: …

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

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

    2024年11月26日
    00
  • 在Java中 ArrayList 和 LinkedList 实现 List 接口类

    在Java中,ArrayList 和 LinkedList 都是实现了 List 接口的类,但它们在底层实现和使用场景上有显著的区别。以下是它们的主要区别: 1. 底层实现ArrayList基于动态数组实现。元素是连续存储的,每个元素都可以通过索引直接访问。LinkedList基于双向链表实现。每个元素由节点(Node)存储,节点包含数据和前后节点的引用。 …

    2024年12月2日
    00
  • Android 解决 “Module was compiled with an incompatible version of Kotlin“

    “Module was compiled with an incompatible version of Kotlin” 错误通常出现在 Android 开发中,因为模块的 Kotlin 编译器版本与项目中的 Kotlin 编译器版本不匹配。以下是解决此问题的方法: 1. 检查 Kotlin 插件版本步骤:打开 Android Studio。点击顶部菜单的 …

    2024年11月26日
    00
  • pywebview 页面请求数据总是报错:TypeError: Cannot read properties of undefined (reading ‘api’)

    pywebview 中的 TypeError: Cannot read properties of undefined (reading ‘api’) 错误通常意味着 JavaScript 代码试图访问一个未定义的对象或属性(如 api)。这种问题通常出现在 Python 与前端 JavaScript 交互时,可能是由于以下原因:可能的原因及解决方法:Jav…

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

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

    2024年11月25日
    00
  • 在 .NET 环境下,使用 OpenTK 为 SkiaSharp 提供 OpenGL 支持是一个常见的方式

    在 .NET 环境下,使用 OpenTK 为 SkiaSharp 提供 OpenGL 支持是一个常见的方式,可以高效地进行 2D 图形渲染。下面是具体如何实现和一些关键概念的介绍: 背景知识 实现步骤 1. 添加必要的 NuGet 包 确保你的项目安装了以下 NuGet 包: 2. 创建 OpenGL 上下文 使用 OpenTK 创建一个 OpenGL 上下…

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

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

    2024年11月26日
    00

发表回复

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

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信