C++中vector类型的介绍和使用

文章目录

    • 一、vector 类型的简介
      • 1.1 基本介绍
      • 1.2 常见用法示例
      • 1.3 常见成员函数简表
    • 二、vector 数据的插入
      • 2.1 push_back() —— 在尾部插入一个元素
      • 2.2 emplace_back() —— 在尾部“就地”构造对象
      • 2.3 insert() —— 在任意位置插入一个或多个元素
      • 2.4 emplace() —— 在任意位置就地构造对象
      • 2.5 assign() —— 替换整个 vector 的内容
    • 三、vector 数据的遍历
      • 3.1 范围-based for 循环(C++11 起)
      • 3.2 使用下标访问
      • 3.3 使用迭代器
      • 3.4 使用 std::for_each 和 Lambda(C++11 起)
    • 四、vector 数据的删除
      • 4.1 删除尾部元素:pop_back()
      • 4.2 按下标删除一个元素:erase(iterator)
      • 4.3 删除一个区间:erase(begin, end)
      • 4.4 按值删除(配合 remove)
      • 4.5 按条件删除(用 lambda)
      • 4.6 清空整个 vector:clear()
      • 4.7 删除自定义类型的元素(按值或条件)
      • 4.8 删除某个元素再次遍历

一、vector 类型的简介

  vector 是 C++ 标准模板库(STL)中最常用的顺序容器之一,底层实现为 动态数组。它提供动态增长、随机访问、高效末尾插入等特性。

1.1 基本介绍

#include <vector>
std::vector<int> numbers;

在这里插入图片描述

1.2 常见用法示例

初始化方式

std::vector<int> v1;                     // 空向量
std::vector<int> v2(5);                  // 5个默认值(0)
std::vector<int> v3(5, 42);              // 5个 42
std::vector<int> v4 = {1, 2, 3, 4};      // 列表初始化

常用操作

v1.push_back(10);       // 尾部添加元素
v1.pop_back();          // 删除最后一个元素
v1.size();              // 元素数量
v1.empty();             // 是否为空
v1.clear();             // 清空所有元素
v1.at(2);               // 安全访问第3个元素(带边界检查)
v1[2];                  // 快速访问第3个元素(无检查)

遍历方式

for (size_t i = 0; i < v1.size(); ++i)std::cout << v1[i] << std::endl;for (int x : v1)        // C++11 范围循环std::cout << x << std::endl;

1.3 常见成员函数简表

在这里插入图片描述

二、vector 数据的插入

  std::vector 提供多种方式将数据插入容器中,适用于不同的使用场景(如单个元素插入、批量插入、自定义位置插入等)。

2.1 push_back() —— 在尾部插入一个元素

特点:时间复杂度均摊为 O(1)

示例:

std::vector<int> v;
v.push_back(10);
v.push_back(20);  // v = {10, 20}

2.2 emplace_back() —— 在尾部“就地”构造对象

特点:

  • 避免临时对象拷贝或移动
  • 构造更复杂类型推荐使用

示例:

std::vector<std::pair<int, std::string>> v;
v.emplace_back(1, "Alice");  // 直接构造 pair(1, "Alice")

2.3 insert() —— 在任意位置插入一个或多个元素

重载形式包括:

插入单个元素

std::vector<int> v = {1, 2, 4};
v.insert(v.begin() + 2, 3);  // v = {1, 2, 3, 4}

插入多个相同元素

v.insert(v.begin(), 3, 100);  // 插入3个100在开头

插入另一 vector 的一段范围

std::vector<int> v1 = {1, 2};
std::vector<int> v2 = {10, 20, 30};
v1.insert(v1.end(), v2.begin(), v2.end());  // v1 = {1, 2, 10, 20, 30}

2.4 emplace() —— 在任意位置就地构造对象

类似于 insert(),但对象是“就地构造”而非拷贝。

示例:

std::vector<std::pair<int, std::string>> v;
v.emplace(v.begin(), 1, "Bob");  // 插入 pair(1, "Bob") 到开头

2.5 assign() —— 替换整个 vector 的内容

注意这是替换整个内容,不是插入。

std::vector<int> v;
v.assign(5, 42);  // v = {42, 42, 42, 42, 42}

插入方式对比表
在这里插入图片描述

三、vector 数据的遍历

3.1 范围-based for 循环(C++11 起)

#include <vector>
#include <iostream>std::vector<int> vec = {1, 2, 3, 4, 5};for (int value : vec) {std::cout << value << " ";
}

3.2 使用下标访问

for (size_t i = 0; i < vec.size(); ++i) {std::cout << vec[i] << " ";
}

也可以用 at() 提供边界检查:

for (size_t i = 0; i < vec.size(); ++i) {std::cout << vec.at(i) << " ";
}

3.3 使用迭代器

for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";
}

如果不需要修改数据,可使用 const_iterator:

for (std::vector<int>::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) {std::cout << *it << " ";
}

3.4 使用 std::for_each 和 Lambda(C++11 起)

#include <algorithm>std::for_each(vec.begin(), vec.end(), [](int value) {std::cout << value << " ";
});

四、vector 数据的删除

4.1 删除尾部元素:pop_back()

std::vector<int> vec = {1, 2, 3};
vec.pop_back(); // 删除最后一个元素(3)

4.2 按下标删除一个元素:erase(iterator)

std::vector<int> vec = {10, 20, 30, 40};
vec.erase(vec.begin() + 2); // 删除索引为2的元素(30)

4.3 删除一个区间:erase(begin, end)

std::vector<int> vec = {1, 2, 3, 4, 5};
vec.erase(vec.begin() + 1, vec.begin() + 4); // 删除 2, 3, 4
// 结果为 vec = {1, 5}

4.4 按值删除(配合 remove)

#include <algorithm>std::vector<int> vec = {1, 2, 3, 2, 4};
// 删除所有值为 2 的元素
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
// 结果为 vec = {1, 3, 4}

注意:std::remove 不是真正删除,而是将不符合条件的元素移到后面,返回“新逻辑末尾”,再用 erase 删除尾部的冗余数据。

4.5 按条件删除(用 lambda)

// 删除所有大于3的元素
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x) {return x > 3;
}), vec.end());

4.6 清空整个 vector:clear()

vec.clear(); // 删除所有元素,size() 为 0

4.7 删除自定义类型的元素(按值或条件)

struct Person {std::string name;int age;
};std::vector<Person> people = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 25}
};// 删除所有 age 为 25 的人
people.erase(std::remove_if(people.begin(), people.end(), [](const Person& p) {return p.age == 25;
}), people.end());

4.8 删除某个元素再次遍历

方法 1:使用 erase + iterator,正确方式如下:

#include <vector>
#include <iostream>int main() {std::vector<int> vec = {1, 2, 3, 2, 4};for (auto it = vec.begin(); it != vec.end(); ) {if (*it == 2) {it = vec.erase(it);  // erase 返回新的 iterator,指向被删元素的下一个位置} else {++it;}}// 再次遍历for (int val : vec) {std::cout << val << " ";}return 0;
}

方法 2:先删除,再单独遍历(更清晰):

vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());// 再次遍历
for (int val : vec) {std::cout << val << " ";
}

错误示例(不要这样做):

for (auto it = vec.begin(); it != vec.end(); ++it) {if (*it == 2) {vec.erase(it); // ❌ it 会失效,下一次 ++it 就是未定义行为}
}

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

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

相关文章

在Vue或React项目中使用Tailwind CSS实现暗黑模式切换:从系统适配到手动控制

在现代Web开发中&#xff0c;暗黑模式(Dark Mode)已成为提升用户体验的重要功能。本文将带你使用Tailwind CSS在React项目(Vue项目类似)中实现两种暗黑模式控制方式&#xff1a; 系统自动适配 - 根据用户设备偏好自动切换手动切换 - 通过按钮让用户自由选择 一、项目准备 使…

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…

Tomcat 安装和配置

一、Tomcat官网 Apache Tomcat - Welcome! 选择解压到任意一个盘&#xff01;&#xff01; 二、Tomcat配置 1&#xff09;在系统变量处新建一个变量CATALINA_HOME。CATALINA_HOME环境变量的值&#xff0c;设置为Tomcat的解压安装目录 2&#xff09;找到系统变量Path&#xff0…

动态规划 熟悉30题 ---上

本来是要写那个二维动态规划嘛&#xff0c;但是我今天在问题时候&#xff0c;一个大佬就把他初一时候教练让他练dp的30题发出来了&#xff08;初一&#xff0c;啊虽然知道计算机这一专业&#xff0c;很多人从小就学了&#xff0c;但是我每次看到一些大佬从小学还是会很羡慕吧或…

基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)

注&#xff1a;成品使用演示、项目源码、项目文档在文章末尾网盘链接中自取 所用硬件&#xff1a;STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …

时间同步技术在电力系统中的应用

随着电力自动化技术的发展&#xff0c;时间同步不仅可以为电力系统的事后故障分析提供支持&#xff0c;而且已经参与到电力系统的实时控制中来&#xff0c;其可靠性对电力系统的稳定运行影响越来越大。在电力系统中&#xff0c;时间同步技术广泛应用于调度控制中心、发电厂、变…

XMLGregorianCalendar跟Date、localDateTime以及String有什么区别

1. java.util.Date&#xff08;已过时&#xff0c;不推荐新代码使用&#xff09; 特点 表示时间戳&#xff1a;存储自 1970-01-01 00:00:00 UTC&#xff08;Unix 纪元&#xff09; 以来的毫秒数。 问题&#xff1a; 不区分日期和时间&#xff0c;也没有时区支持&#xff08;依…

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…

玩转抖音矩阵:核心玩法与高效运营规则

一、 抖音矩阵&#xff1a;流量协同的生态网络 抖音矩阵&#xff0c;本质是运营一个相互关联、互相支持的抖音账号群。核心目标在于通过账号间的深度协同&#xff08;内容、流量、粉丝&#xff09;&#xff0c;打破单个账号的流量天花板&#xff0c;实现11>2的效果。它不仅…

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…

用电脑通过USB总线连接控制keysight示波器

通过USB总线控制示波器的优势 在上篇文章我介绍了如何通过网线远程连接keysight示波器&#xff0c;如果连接的距离不是很远&#xff0c;也可以通过USB线将示波器与电脑连接起来&#xff0c;实现对示波器的控制和截图。 在KEYSIGHT示波器DSOX1204A的后端&#xff0c;除了有网口…

StarRocks 全面向量化执行引擎深度解析

StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计&#xff0c;相比传统行式处理引擎&#xff08;如MySQL&#xff09;&#xff0c;性能可提升 5-10倍。以下是分层拆解&#xff1a; 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…

02 Deep learning神经网络的编程基础 逻辑回归--吴恩达

1.逻辑回归 逻辑回归是一种用于解决二分类任务&#xff08;如预测是否是猫咪等&#xff09;的统计学习方法。尽管名称中包含“回归”&#xff0c;但其本质是通过线性回归的变体输出概率值&#xff0c;并使用Sigmoid函数将线性结果映射到[0,1]区间。 以猫咪预测为例 假设单个…

UDP 与 TCP 的区别是什么?

UDP&#xff08;用户数据报协议&#xff09;与TCP&#xff08;传输控制协议&#xff09;有以下区别&#xff1a; 连接方式 - UDP&#xff1a;无连接&#xff0c;发送数据前不需要建立连接&#xff0c;也不维护连接状态&#xff0c;因此UDP的通信效率较高&#xff0c;适合对实时…

6.计算机网络核心知识点精要手册

计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法&#xff1a;数据与控制信息的结构或格式&#xff0c;如同语言中的语法规则语义&#xff1a;控制信息的具体含义和响应方式&#xff0c;规定通信双方"说什么"同步&#xff1a;事件执行的顺序与时序…

unipp---HarmonyOS 应用开发实战

HarmonyOS 应用开发实战指南 1. 开篇&#xff1a;为什么选择 HarmonyOS&#xff1f; 最近在开发鸿蒙应用时&#xff0c;发现很多开发者都在问&#xff1a;为什么要选择 HarmonyOS&#xff1f;这里分享一下我的看法&#xff1a; 生态优势 华为手机用户基数大&#xff0c;市场潜…

Python_day48随机函数与广播机制

在继续讲解模块消融前&#xff0c;先补充几个之前没提的基础概念 尤其需要搞懂张量的维度、以及计算后的维度&#xff0c;这对于你未来理解复杂的网络至关重要 一、 随机张量的生成 在深度学习中经常需要随机生成一些张量&#xff0c;比如权重的初始化&#xff0c;或者计算输入…

C++中的数组

在C中&#xff0c;数组是存储固定大小同类型元素的连续内存块。它是最基础的数据结构之一&#xff0c;广泛用于各种场景。以下是关于数组的详细介绍&#xff1a; 一、一维数组 1. 定义与初始化 语法&#xff1a;类型 数组名[元素个数];示例&#xff1a;int arr[5]; // 定义…

three.js 零基础到入门

three.js 零基础到入门 什么是 three.js为什么使用 three.js使用 Three.js1. 创建场景示例 2.创建相机3. 创建立方体并添加网格地面示例 5. 创建渲染器示例 6. 添加效果(移动/雾/相机跟随物体/背景)自动旋转示例效果 相机自动旋转示例 展示效果 实现由远到近的雾示例展示效果 T…

Elasticsearch的写入性能优化

优化Elasticsearch的写入性能需要从多维度入手,包括集群配置、索引设计、数据处理流程和硬件资源等。以下是一些关键优化策略和最佳实践: 一、索引配置优化 合理设置分片数与副本数分片数(Shards):过少会导致写入瓶颈(无法并行),过多会增加集群管理开销。公式参考:分…