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

相关推荐

  • uni-app 中的一个 API,uni.getLocation用于获取用户的地理位置信息

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

    2024年11月28日
    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
  • 理解 HTML、HTML5 和 “H5” 区别的重要性

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

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

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

    2024年11月25日
    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
  • Spring Boot 项目中对接海康摄像头的视频流播放

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

    2024年11月24日
    00
  • 锁策略和优化是并发编程 synchronized 的优化,JVM 与编译器的锁优化

    锁策略和优化是并发编程中的重要话题,特别是在 Java 中,synchronized 作为基本的内置锁机制,得到了多层次的优化。在 JVM 和编译器层面,也有多种优化策略以提升锁的性能。 1. 锁策略:不同场景下的锁机制选择 2. synchronized 的优化 2.1 早期问题 在 Java 1.5 之前,synchronized 的实现依赖重量级锁,直…

    2024年11月24日
    00
  • C语言中的操作符(Operators)对数据进行运算的符号

    C语言中的操作符(Operators)是对数据进行运算的符号,分为多种类型,支持从基本算术到复杂的逻辑操作。以下是C语言操作符的详解: 1. 算术操作符(Arithmetic Operators) 用于执行基本数学运算: 示例: 2. 关系操作符(Relational Operators) 用于比较两个值,结果为布尔值: 示例: 3. 逻辑操作符(Logic…

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

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

    2024年11月25日
    00
  • 实现微信支付提现api接口教程

    微信支付的提现功能,通常是通过调用 企业付款到零钱 API 或 企业付款到银行卡 API 来实现的。以下是如何使用微信支付提现 API 的详细教程,包括其前置条件、接口调用以及注意事项。 1. 准备工作 1.1. 开通微信支付商户号 1.2. 配置证书 将这些文件保存在你的服务器上,用于发起 HTTPS 请求。 1.3. 获取 API 密钥 2. 企业付款到…

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

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

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

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

    2024年11月29日
    00
  • Python与Jupyter Notebook中的数据可视化实现

    数据可视化是分析和展示数据的重要手段,而 Python 与 Jupyter Notebook 是构建交互式数据可视化的重要工具组合。以下是如何在 Python 和 Jupyter Notebook 中实现数据可视化的详细介绍。 1. 常用数据可视化库Python 中有多个强大的可视化库,以下是几个常用的:1.1 Matplotlib特点:功能强大、灵活,但语…

    2024年11月26日
    00
  • 在 Delphi 中创建一个像 C# 那样的 DLL 类库(即面向对象的 DLL)

    在 Delphi 中创建一个像 C# 那样的 DLL 类库(即面向对象的 DLL)可以通过以下步骤实现:1. 创建 Delphi DLL 项目打开 Delphi。选择 File > New > Other > Dynamic-Link Library。在新项目中,默认生成的代码通常是 exports 部分,其中包含了 DLL 导出的函数。2. 定义类你可以在…

    2024年11月29日
    00

发表回复

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

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信