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

相关推荐

  • XiYan-SQL 是一种多生成器集成的 Text-to-SQL框架,专注于将自然语言查询转换为结构化查询语言

    XiYan-SQL 是一种多生成器集成的 Text-to-SQL(文本转 SQL)框架,专注于将自然语言查询转换为结构化查询语言(SQL),从而高效地与数据库交互。以下是该框架的主要特点、技术原理及其应用场景的解析: 1. XiYan-SQL 的核心特点 2. 核心技术原理 3. 应用场景 4. XiYan-SQL 的优势 5. 示例 输入: 自然语言查询:…

    2024年12月5日
    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
  • 在 Nuxt.js 应用中,webpack 的 compile 事件钩子构建过程

    在 Nuxt.js 应用中,webpack 的 compile 事件钩子通常用于在构建过程中处理或监听 Webpack 编译的状态。webpack 是 Nuxt.js 中的核心构建工具之一,而 Nuxt.js 本身是基于 Webpack 配置的,允许你通过扩展 Webpack 配置来进行自定义。要使用 webpack 的 compile 事件钩子,首先你需要…

    2024年11月29日
    00
  • Java 8 到 Java 17 的升级涉及一些关键变化

    JDK 8 升级到 JDK 17 指南Java 8 到 Java 17 的升级涉及一些关键变化,包括语言特性、API 更新和性能改进。以下是一些升级要点:语法和语言特性:记录类(Record Class):Java 14 引入了记录类,提供了一种简化创建不可变数据对象的方式。密封类(Sealed Classes):Java 15 引入了密封类,允许开发者限制…

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

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

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

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

    2024年11月27日
    00
  • 在 .NET 8 框架中使用 Web API 项目并通过引用 SqlSugar ORM 来操作数据库

    在 .NET 8 框架中使用 Web API 项目并通过引用 SqlSugar ORM 来操作数据库,可以遵循以下步骤: 1. 准备工作确保已安装 .NET 8 SDK 和 SqlSugar NuGet 包。创建或打开现有的 Web Core API 项目。安装 SqlSugar NuGet 包: 2. 配置 SqlSugar在 Web API 项目中配置 …

    2024年11月27日
    00
  • C语言内存函数动态分配内存、释放内存和对内存内容进行操作。

    C语言中的内存函数主要用于动态分配内存、释放内存和对内存内容进行操作。这些函数都在标准库 <stdlib.h> 和 <string.h> 中定义。以下是 C 语言常用的内存函数及其详细说明: 1. 动态内存管理函数 这些函数位于 <stdlib.h> 中,用于在运行时分配和释放内存。 1.1 malloc 示例: 功能:分配一块指定大…

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

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

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

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

    2024年12月8日
    00
  • 通过 PHP 读取微软邮箱(Outlook/Office 365 邮箱)

    通过 PHP 读取微软邮箱(Outlook/Office 365 邮箱)邮件,通常需要使用 Microsoft Graph API,因为微软逐步淘汰了基于用户名和密码的 IMAP/SMTP 方式。Microsoft Graph API 支持 OAuth2.0 认证,可以安全地访问和管理用户邮件。 以下是实现读取微软邮箱邮件的完整示例。 实现步骤 1. 准备工…

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

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

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

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

    2025年1月18日
    00
  • 开源工具 Flowise 构建可视化的 AI 工作流

    Flowise 是一个开源的工具,用于构建可视化的 AI 工作流和对话代理。通过 Flowise,用户可以快速集成各种大语言模型(LLM)并与数据库交互。以下是详细的本地部署教程: 1. 前置条件 1.1 硬件和系统要求 1.2 软件要求 2. 本地部署步骤 2.1 克隆 Flowise 代码库 2.2 安装依赖 2.3 配置环境变量 2.4 启动服务 运行…

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

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

    2024年11月28日
    00

发表回复

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

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信