C++ vector 核心知识:常用操作与示例详解

news2025/3/15 16:27:36

        在C++编程中,vector 是标准模板库(STL)中最常用的容器之一。它以其动态数组的特性、高效的尾部操作和便捷的随机访问能力,成为处理动态数据的首选工具。无论是初学者还是经验丰富的开发者,掌握 vector 的使用方法和性能优化技巧,都是提升代码效率的关键。

        然而,vector 的强大功能背后也隐藏着一些需要注意的细节,例如动态扩容的开销、迭代器失效问题以及不同操作的性能差异

一、vector 容器概述

  • 定义vector 是C++标准模板库(STL)中的动态数组,支持随机访问、动态扩容和高效尾部操作。

  • 特点

    • 内存连续存储,支持快速随机访问(时间复杂度 O(1))。

    • 尾部插入/删除高效(均摊 O(1)),中间或头部操作效率较低(O(n))。

    • 自动管理内存,动态调整容量(通过 reserve 可手动优化)。


二、vector 常用操作及示例

1. 构造函数与初始化

操作功能说明示例代码
默认构造创建空 vectorvector<int> v1;
指定大小和初始值创建大小为 n 的 vectorvector<int> v2(5, 10); // 5个元素,值10
通过迭代器初始化用其他容器的范围初始化vector<int> v3(v2.begin(), v2.end());
列表初始化(C++11)直接通过列表初始化vector<int> v4 = {1, 2, 3, 4};

2. 元素访问

操作功能说明示例代码时间复杂度
v[i]访问第 i 个元素(不检查越界)int x = v[2];O(1)
v.at(i)访问第 i 个元素(检查越界)int y = v.at(3); // 越界抛出异常O(1)
v.front()访问第一个元素int first = v.front();O(1)
v.back()访问最后一个元素int last = v.back();O(1)
v.data()获取底层数组指针int* p = v.data();O(1)

3. 容量操作

操作功能说明示例代码时间复杂度
v.empty()判断容器是否为空if (v.empty()) { ... }O(1)
v.size()返回元素个数int n = v.size();O(1)
v.capacity()返回当前分配的容量int cap = v.capacity();O(1)
v.reserve(n)预分配容量(避免多次扩容)v.reserve(100);O(n)
v.shrink_to_fit()请求释放未使用的内存v.shrink_to_fit();O(n)

4. 修改操作

操作功能说明示例代码时间复杂度
v.push_back(val)在尾部插入元素v.push_back(10);均摊 O(1)
v.pop_back()删除尾部元素v.pop_back();O(1)
v.insert(pos, val)在 pos 位置插入元素v.insert(v.begin() + 2, 20);O(n)
v.erase(pos)删除 pos 位置的元素v.erase(v.begin() + 1);O(n)
v.clear()清空所有元素v.clear();O(n)
v.resize(n)调整容器大小为 nv.resize(10); // 新元素默认初始化O(n)
v.emplace_back(args)在尾部直接构造元素(避免拷贝)v.emplace_back(10);均摊 O(1)

5. 遍历操作

操作功能说明示例代码
范围for循环(C++11)遍历所有元素for (int x : v) { cout << x << " "; }
迭代器遍历使用迭代器遍历for (auto it = v.begin(); it != v.end(); ++it) { ... }

三、代码示例

1. 基本操作示例

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 初始化
    vector<int> vec = {1, 2, 3, 4, 5};

    // 尾部插入元素
    vec.push_back(6);          // vec: {1, 2, 3, 4, 5, 6}

    // 访问元素
    cout << "Third element: " << vec[2] << endl;  // 输出: 3
    cout << "Last element: " << vec.back() << endl; // 输出: 6

    // 删除尾部元素
    vec.pop_back();            // vec: {1, 2, 3, 4, 5}

    // 插入元素
    vec.insert(vec.begin() + 2, 10); // vec: {1, 2, 10, 3, 4, 5}

    // 删除元素
    vec.erase(vec.begin() + 3);      // vec: {1, 2, 10, 4, 5}

    // 遍历输出
    for (int x : vec) {
        cout << x << " ";       // 输出: 1 2 10 4 5
    }

    return 0;
}

2. 容量管理示例

#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec;
    cout << "Initial capacity: " << vec.capacity() << endl; // 输出: 0

    vec.reserve(5);  // 预分配容量为5
    for (int i = 0; i < 10; ++i) {
        vec.push_back(i);
        cout << "Size: " << vec.size() 
             << ", Capacity: " << vec.capacity() << endl;
    }
    // 容量会自动扩展(具体策略依赖实现,如翻倍扩容)

    vec.shrink_to_fit(); // 释放多余内存
    return 0;
}

3.更多例子

#include <bits/stdc++.h>  // 包含标准库的所有头文件
using namespace std;       // 使用标准命名空间

int main() {              // 主函数开始
    vector<int> a;        // 初始化一个 size 为 0 的 vector
    a.insert(a.begin(), 4, 2);  // 在 a 的开始位置插入 4 个值为 2 的元素

    // 下面的 4 个 for 是 4 种遍历方法
    for (int i = 0; i < a.size(); i++)  // 通过下标访问,输出 2 2 2 2
        cout << a[i] << " "; cout << "\n";  // 输出每个元素

    for (vector<int>::iterator it = a.begin(); it != a.end(); ++it)  // 通过迭代器访问
        cout << *it << " "; cout << "\n";  // 输出每个元素

    for (auto it = a.begin(); it != a.end(); ++it)  // 用 auto 获得迭代器
        cout << *it << " "; cout << "\n";  // 输出每个元素

    for (auto i : a)  // 直接访问 vector 中的每个元素
        cout << i << " "; cout << "\n";  // 输出每个元素

    a.insert(a.begin() + 1, 9);  // 在 a[1] 处插入 9, a = {2 9 2 2 2}
    a.insert(a.begin() + 2, 2, 5);  // 在 a[2] 处插入两个 5, a = {2 9 5 5 2 2 2}
    a.resize(3);  // 改变 a 的大小为 3, a = {2 9 5}

    vector<int> c(a);  // 复制 a 到 c
    vector<int> b;     // 初始化一个空的 vector b
    b.insert(b.begin(), a.begin(), a.begin() + 3);  // 将 a 的前 3 个数复制到 b

    // 下面演示二维 vector
    vector<vector<char>> ch(2, vector<char>(3, '#'));  // 初始化一个 2 行 3 列的二维 vector,所有元素为 '#'
    for (int i = 0; i < 2; i++) {  // 遍历行
        for (int j = 0; j < 3; j++)  // 遍历列
            cout << ch[i][j];  // 输出每个元素
        cout << "\n";
    }

    // 下面演示用 vector 存储物体
    struct point { int x, y; };  // 定义一个结构体 point,包含两个整型成员 x 和 y
    vector<point> PP;  // 初始化一个存储 point 结构体的 vector
    for (int i = 0; i < 3; i++) {  // 循环 3 次
        point t; t.x = i; t.y = i;  // 创建一个 point 对象 t,并赋值
        PP.push_back(t);  // 将 t 添加到 PP 中
    }

    for (int i = 0; i < PP.size(); i++)  // 遍历 PP
        cout << PP[i].x << " " << PP[i].y << "\n";  // 输出每个 point 的 x 和 y

    auto it = PP.begin();  // 获取 PP 的起始迭代器
    for (; it != PP.end(); ++it)  // 使用迭代器遍历 PP
        cout << it->x << " " << it->y << "\n";  // 输出每个 point 的 x 和 y

    return 0;  // 主函数结束
}

四、总结

  1. 优点

    • 快速随机访问(通过下标或迭代器)。

    • 尾部插入/删除高效。

    • 内存自动管理,支持动态扩容。

  2. 缺点

    • 中间或头部插入/删除效率低(需移动元素)。

    • 频繁扩容可能影响性能(可通过 reserve 优化)。

  3. 适用场景

    • 需要频繁随机访问元素。

    • 尾部操作较多,中间操作较少。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2315542.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MacOS 15.3.1 安装 GPG 提示Error: unknown or unsupported macOS version: :dunno

目录 1. 问题锁定 2. 更新 Homebrew 3. 切换到新的 Homebrew 源 4. 安装 GPG 5. 检查 macOS 版本兼容性 6. 使用 MacPorts 或其他包管理器 7. 创建密钥&#xff08;生成 GPG 签名&#xff09; 往期推荐 1. 问题锁定 通常是因为你的 Homebrew 版本较旧&#xff0c;或者你…

硬件驱动——51单片机:独立按键、中断、定时器/计数器

目录 一、独立按键 1.原理 2.封装函数 3.按键控制点灯 数码管 二、中断 1.原理 2.步骤 3.中断寄存器IE 4.控制寄存器TCON 5.打开外部中断0和1 三、定时器/计数器 1.原理 2.控制寄存器TCON 3.工作模式寄存器TMOD 4.按键控制频率的动态闪烁 一、独立按键 1…

P1259 黑白棋子的移动【java】【AC代码】

有 2n 个棋子排成一行&#xff0c;开始为位置白子全部在左边&#xff0c;黑子全部在右边&#xff0c;如下图为 n5 的情况&#xff1a; 移动棋子的规则是&#xff1a;每次必须同时移动相邻的两个棋子&#xff0c;颜色不限&#xff0c;可以左移也可以右移到空位上去&#xff0c;但…

67.Harmonyos NEXT 图片预览组件之性能优化策略

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; Harmonyos NEXT 图片预览组件之性能优化策略 文章目录 Harmonyos NEXT 图片预览组件之性能优化策略效果预览一、性能优化概述1. 性能优化的关键指标…

Windows下安装Git客户端

① 官网地址&#xff1a;https://git-scm.com/。 ② Git的优势 大部分操作在本地完成&#xff0c;不需要联网&#xff1b;完整性保证&#xff1b;尽可能添加数据而不是删除或修改数据&#xff1b;分支操作非常快捷流畅&#xff1b;与Linux 命令全面兼容。 ③ Git的安装 从官网…

SAP IBP for Supply Chain Certification Guide (Parag Bakde, Rishabh Gupta)

SAP IBP for Supply Chain Certification Guide (Parag Bakde, Rishabh Gupta)

如何处理PHP中的日期和时间问题

如何处理PHP中的日期和时间问题 在PHP开发中&#xff0c;日期和时间的处理是一个常见且重要的任务。无论是记录用户操作时间、生成时间戳&#xff0c;还是进行日期计算&#xff0c;PHP提供了丰富的函数和类来帮助开发者高效处理这些需求。本文将详细介绍如何在PHP中处理日期和…

TDengine 使用最佳实践

简介 阅读本文档需要具备的基础知识&#xff1a; Linux系统的基础知识&#xff0c;及基本命令网络基础知识&#xff1a;TCP/UDP、http、RESTful、域名解析、FQDN/hostname、hosts、防火墙、四层/七层负载均衡 本文档的阅读对象有&#xff1a;架构师、研发工程师&#xff0c;…

Spring、Spring Boot、Spring Cloud 的区别与联系

1. Spring 框架 定位&#xff1a;轻量级的企业级应用开发框架&#xff0c;核心是 IoC&#xff08;控制反转&#xff09; 和 AOP&#xff08;面向切面编程&#xff09;。 核心功能&#xff1a; 依赖注入&#xff08;DI&#xff09;&#xff1a;通过 Autowired、Component 等注解…

AutoGen-构建问答智能体

概述 如https://github.com/microsoft/autogen所述&#xff0c;autogen是一多智能体的框架&#xff0c;属于微软旗下的产品。 依靠AutoGen我们可以快速构建出一个多智能体应用&#xff0c;以满足我们各种业务场景。 环境说明 python&#xff0c;3.10AutoGen&#xff0c;0.4.2…

C语言实现括号匹配检查及栈的应用详解

目录 栈数据结构简介 C语言实现栈 栈的初始化 栈的销毁 栈的插入 栈的删除 栈的判空 获取栈顶数据 利用栈实现括号匹配检查 总结 在编程中&#xff0c;经常会遇到需要检查括号是否匹配的问题&#xff0c;比如在编译器中检查代码的语法正确性&#xff0c;或者在…

阿里云魔笔低代码应用开发平台快速搭建教程

AI低代码&#xff0c;大模型时代应用开发新范式 什么是魔笔 介绍什么是魔笔低代码应用开发平台。 魔笔是一款面向全端&#xff08;Web、H5、全平台小程序、App&#xff09;场景的模型驱动低代码开发平台&#xff0c;提供一站式的应用全生命周期管理&#xff0c;包括可视化开发…

A Survey on Mixture of Experts 混合专家模型综述(第二部分:混合专家系统设计)

A Survey on Mixture of Experts 混合专家模型综述 (第一部分&#xff1a;混合专家算法设计) A Survey on Mixture of Experts arxiv github&#xff1a;A-Survey-on-Mixture-of-Experts-in-LLMs ​ ​ ​ 5 System Design of Mixture of Experts While ​Mixture of Exper…

docker python:latest镜像 允许ssh远程

跳转到家目录 cd创建pythonsshdockerfile mkdir pythonsshdockerfile跳转pythonsshdockerfile cd pythonsshdockerfile创建Dockerfile文件 vim Dockerfile将Dockerfile的指令复制到文件中 # 使用 python:latest 作为基础镜像 # 如果我的镜像列表中没有python:latest镜像&…

Aim Robotics电动胶枪:机器人涂胶点胶的高效解决方案

在自动化和智能制造领域&#xff0c;机器人技术的应用越来越广泛&#xff0c;而涂胶和点胶作为生产过程中的重要环节&#xff0c;也逐渐实现了自动化和智能化。Aim Robotics作为一家专注于机器人技术的公司&#xff0c;其推出的电动胶枪为这一领域带来了高效、灵活且易于操作的…

【HDLbits--分支预测器简单实现】

HDLbits--分支预测器简单实现 1 timer2.branche predicitors3.Branch history shift4.Branch direction predictor 以下是分支预测器的简单其实现&#xff1b; 1 timer 实现一个计时器&#xff0c;当load1’b1时&#xff0c;加载data进去&#xff0c;当load1’b0时进行倒计时&…

Linux--操作系统/进程

ok&#xff0c;我们今天学习linux中的操作系统和进程 1. 冯诺依曼体系 我们常⻅的计算机&#xff0c;如笔记本。我们不常⻅的计算机&#xff0c;如服务器&#xff0c;⼤部分都遵守冯诺依曼体系。 内存是CPU和外设之间的一个巨大的缓存&#xff01; 截⾄⽬前&#xff0c;我们…

Java面试八股—Redis篇

一、Redis的使用场景 &#xff08;一&#xff09;缓存 1.Redis使用场景缓存 场景&#xff1a;缓存热点数据&#xff08;如用户信息、商品详情&#xff09;&#xff0c;减少数据库访问压力&#xff0c;提升响应速度。 2.缓存穿透 正常的访问是&#xff1a;根据ID查询文章&…

Web后端开发之Maven

Maven Mven是apache旗下的一个开源项目&#xff0c;用来管理和构建java项目的工具。 通过一小段描述信息来管理项目。 Maven的作用 1.依赖管理&#xff1a;方便快捷的管理项目依赖的资源&#xff08;jar包&#xff09;&#xff0c;避免版本冲突问题 以前用某个jar包需要下载…

there are no enabled repos

我做了两个操作 第一个操作&#xff1a; 1.先在本地电脑&#xff0c;也就是在我们电脑的桌面上下载 https://repo.huaweicloud.com/repository/conf/CentOS-7-reg.repo 2.在CentOS 创建etc文件夹 3在etc文件夹内创建yum.repos.d文件夹 4.将下载好的repo 黏贴到yum.repos.d…