C++ std::vector删除元素的几种方式及区别

2023-10-29

容器vector在删除过程中,常用的函数。

函数 作用
pop_back() 删除 vector 容器中最后一个元素,该容器的大小(size)会减 1,但容量(capacity)不会发生改变。
erase(iter) 删除 vector 容器中iter迭代器指定位置处的元素,并返回指向被删除元素下一个位置元素的迭代器。该容器的大小(size)会减 1,但容量(capacity)不会发生改变。
erase(iter1,iter2) 删除 vector 容器中位于迭代器 [iter1,iter2)指定区域内的所有元素,并返回指向被删除区域下一个位置元素的迭代器。该容器的大小(size)会减小,但容量(capacity)不会发生改变。
clear() 删除 vector 容器中所有的元素,使其变成空的 vector 容器。该函数会改变 vector 的大小(变为 0),但不是改变其容量。
remove(iter1,iter2,key) 删除容器中所有和指定元素值相等的元素,并返回指向最后一个元素下一个位置的迭代器。值得一提的是,调用该函数不会改变容器的大小和容量。(后面会详细说明,该函数的用法)
swap(vector) 用于交换向量的内容,用一个向量调用它并接受另一个向量作为参数并交换它们的内容。 (两个向量的大小可能不同)。通过交换向量进行删除。
shrink_to_fit() 将vector 容器的容量缩减至和实际存储元素的个数相等。可以配合以上的函数,收回内存

注意:

  • 容器的大小size:容器实际存放元素的数量。

  • 容器的容量capacity:容器在内存中开辟空间的容量(在不开辟新的空间时,能存放数据的大小)。

1. 使用earse和remove配合删除容器中指定值的元素

remove函数本质上其实并没有完成元素的完全删除工作,因为容器的大小都没有改变,它只是将所有被删除的元素用下一个不被删除的元素进行覆盖,同时返回一个迭代器,在该迭代器之前的所有元素,保留原容器的顺序,并且不存在被删除的元素,也就是你想要的容器内容,而该迭代器到容器的末尾则不变,也就是说,原容器的大小没有发生变化,被删除的元素也确实没有了,但容器末尾的一些元素(个数等于被删除元素个数)又会多出来一份,这是我们不愿意看到的,因此需要借助上面提到的erase函数。所以说remove需要和erase搭配使用才能实现完整的删除功能。

  • 单独使用remove
#include <iostream>
#include <vector>
#include <algorithm>			// [注意] :remove位于algorithm函数库中
int main()
{
    std::vector<int> vecInt{0, 1 , 2 ,3 ,4};

    std::cout << vecInt.size() << std::endl;     // 输出的结果为5,容器中存了5个元素
    std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量

    std::remove(vecInt.begin(), vecInt.end(),3);
    
    std::cout << vecInt.size() << std::endl;     // 输出的结果为5,容器中存了5个元素
    std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量

    for(auto i : vecInt)
    {
        std::cout << i << std::endl;
    }
}
// 使用remove之前,容器vector的值为: 0,1,2,3,4
// 使用remove函数删除值为3的元素后,容器vector的值为:0,1,2,4,4
// 可以看出remove,没有改变容器的size,只是将值为3的元素删除后,将后面的元素,移动到前面(后面的值还保留,因此最后是4)。
  • earse和remove配和使用
#include <iostream>
#include <vector>
#include <algorithm>		// [注意] :remove位于algorithm函数库中
int main()
{
    std::vector<int> vecInt{0, 1 , 2 ,3 ,4};

    std::cout << vecInt.size() << std::endl;     // 输出的结果为5,容器中存了5个元素
    std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量

    vecInt.erase(std::remove(vecInt.begin(), vecInt.end(), 3), vecInt.end());
    
    std::cout << vecInt.size() << std::endl;     // 输出的结果为4,容器中存了4个元素
    std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量

    for(auto i : vecInt)
    {
        std::cout << i << std::endl;
    }
}
// 使用remove之前,容器vector的值为: 0,1,2,3,4
// 使用remove函数删除值为3的元素后,容器vector的值为:0,1,2,4,
// 可以看出remove,容器的size变成了size-1,删除了值为3的元素。容器的capacity不变

注意:

  • remove位于algorithm函数库中,使用时需要调用algorithm头文件。
  • earse和remove不改变vector的容量capacity,(不会收回容器在内存中开辟的空间)

2. 使用swap删除容器的所有元素,并收回内存

  • 使用clear清空容器中的元素
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> vecInt{0, 1 , 2 ,3 ,4};

    std::cout << vecInt.size() << std::endl;     //  输出的结果为5,容器中存了5个元素
    std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量

    vecInt.clear();					// 使用clear清空容器
    
    std::cout << vecInt.size() << std::endl;     // 输出的结果为0,容器中存了0个元素
    std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量
}

可以看出使用clean可以清空vector,但是不会改变capacity,(不会收回容器在内存中开辟的空间)。

  • 使用swap清空容器中的元素
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> vecInt{0, 1, 2, 3, 4};

    std::cout << vecInt.size() << std::endl;      //  输出的结果为5,容器中存了5个元素
    std::cout << vecInt.capacity() << std::endl;  //  输出的结果为5,容器在内存开辟空间的容量

    std::vector<int>().swap(vecInt);		// 使用swap函数,将容器与空的容器交换,从而删除容器数据,并且收回内存
    
    std::cout << vecInt.size() << std::endl;     // 输出的结果为0,容器中存了0个元素
    std::cout << vecInt.capacity() << std::endl; // 输出的结果为0,容器在内存开辟空间的容量
}

使用swap函数,将容器与空的容器交换,从而删除容器所有数据,并且收回内存。

注意:

这里没有为 std::vector() 表达式传递任何参数。这意味着,此表达式将调用 vector 模板类的默认构造函数,而不再是复制构造函数。也就是说,此格式会先生成一个空的 vector 容器,再借助 swap() 方法将空容器交换给 vecInt,从而达到清空 vecInt 的目的。

3. 使用shrink_to_fit()配合其他函数,删除元素并回收内存。

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> vecInt{0, 1, 2, 3, 4};

    vecInt.pop_back(); 				// 删除容器中的最后一个元素
    std::cout << vecInt.size() << std::endl;     // 容器vecInt中元素的数量为4
    std::cout << vecInt.capacity() << std::endl; // 容器vecInt容量为5。
    
    vecInt.shrink_to_fit();				//  将vector 容器的容量缩减至和实际存储元素的个数相等
    
    std::cout << vecInt.size() << std::endl;     // 容器vecInt中元素的数量为4
    std::cout << vecInt.capacity() << std::endl; // 容器vecInt容量为4。
    
    vecInt.clear();				//清空容器

    std::cout << vecInt.size() << std::endl;     // 容器vecInt中元素的数量为0
    std::cout << vecInt.capacity() << std::endl; // 容器vecInt容量为4。

    vecInt.shrink_to_fit();			//  将vector 容器的容量缩减至和实际存储元素的个数相等

    std::cout << vecInt.size() << std::endl;     // 容器vecInt中元素的数量为0
    std::cout << vecInt.capacity() << std::endl; // 容器vecInt容量为0。
}

本文参考:

http://c.biancheng.net/view/6846.html

https://blog.csdn.net/ydyang1126/article/details/60762619

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ std::vector删除元素的几种方式及区别 的相关文章

  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • AI写作可以写什么,分别有哪些工具

    1 开源CLUE AI社区 智能对话模型large v3 是目前最为先进的语言模型 可用于生成各种类型的文本 包括文章 自动回复邮件 自动生成代码等 2 Hugging Face Transformers 是一个面向NLP和AI的开源平台
  • 性价比排序

    链接 https ac nowcoder com acm contest 329 D 来源 牛客网 处女座靠着自己的家教本领赚够了去比赛的钱 于是开启了疯狂训练 在每个夜深人静第二天不收作业的夜晚 他都会开始刷题 今日又是一个刷题的夜晚 他
  • Vulnhub靶机渗透之环境搭建及JIS-CTF入门

    Vulnhub靶机渗透之环境搭建及JIS CTF入门 目录 Vulnhub靶机渗透之环境搭建及JIS CTF入门 一 JIS CTF题目描述 二 Vulnhub环境配置 三 Vulnhub靶机渗透详解 1 信息收集 2 First flag
  • K8s卸载

    sudo kubeadm reset f systemctl stop kubelet kubeadm kubectl yum y remove kubelet kubeadm kubectl sudo rm rvf HOME kube s
  • 基于GEC6818的智能火锅点餐系统

    本次项目开发环境 gec6818 QT5 14 2 SecureCRT 所使用的相关技术 c s架构 STL库 C 封装 标准化代码编写 实现的功能 用户登录页面 食品分区在不同页面 用户点餐页面 用户买单页面 数据整合并发送至后台 后台成
  • 请勿私信或者留言,请写信给我:i@brightguo.com

    请勿留言或者私信给我 一来csdn通知系统经常不及时通知我收到了你们的信息 二来我越来越少上csdn了 这两个原因导致您发了信息给我 我过几个月看到也是正常的 所以请邮件 实时看到您的邮件 像收到短信一样 有空就回复你 i brightgu
  • 操作系统主要知识点

    1 进程管理 1 进程是具有独立功能程序在某个数据集合上的一次执行过程 线程是进程内的一个执行实体或执行单元 进程和线程的区别 a 不同进程的地址空间是独立的 而同一进程内的线程共享同一地址空间 一个进程的线程在另一个进程内是不可见的 b
  • MySQL 数据库 (实现JDBC工具类)

    JDBC工具类 package com itcast ma import java sql Connection import java sql DriverManager import java sql PreparedStatement
  • 用c++写一个贪吃蛇的游戏

    写一个贪吃蛇游戏需要涵盖以下几个方面的知识 图形绘制 使用控制台的图形绘制函数 例如在 Windows 中使用的是 conio h 中的图形绘制函数 游戏逻辑 包括贪吃蛇的移动 食物的生成 检测蛇是否撞墙或撞到自己等 数据存储 使用数组或链
  • 缓存知多少?详解@Cacheable@CacheEvict@Caching

    缓存注解 一 基础概念 1 Cache介绍 2 Cacheable CachePut CacheEvict 的主要参数 二 Cacheable使用demo 三 CacheEvict使用demo 四 Caching使用demo 一 基础概念
  • 代理IP和Socks5代理:跨界电商与爬虫的智能引擎

    跨界电商 作为全球市场的一部分 对数据的需求越来越大 同时 随着互联网的发展 爬虫技术也在不断演进 成为了跨界电商的关键工具之一 然而 随之而来的是网站的反爬虫机制和网络安全风险 在这种情况下 代理IP和Socks5代理应运而生 为企业提供
  • 安卓代码获取系统属性值

    安卓代码获取系统属性值 前言 代码实现 前言 大家可能知道 使用adb shell getprop命令可以直接获取系统属性值 但有时候需要在JAVA代码中获取系统属性 接下来说一下如何实现 代码实现 在build gradle的androi
  • C++获取CPUID

    include
  • 客户流失预测--基于R语言C5.0

    对于中国各大电信运营商而言 在整体市场规模相对稳定的情况下 能否维护好现有的客户是保证其收益的重中之重 因此 预测客户流失的可能性与否 直接关系到运营商的客户维护的重点正确与否 本文将基于 狗熊会 基础案例 收集客户流失 来演示基于C5 0
  • flutter webview 在iOS上不显示的问题

    使用的插件是 webview flutter 0 3 22 1 在android中可以正常显示 但是在ios端中既没有报错 又没有显示出来 后来查看插件使用说明才发现 忘记在ios端中端配置文件中进行配置了 此时我们需要在ios的runne
  • java 包扫描器

    java 包扫描器 扫描指定包下的所有java文件 并返回class数组 直接上代码 import java io File import java net URISyntaxException import java net URL im
  • 【Linux】gcc编译过程、make和makefile的概念与区别、Linux简单进度条实现

    文章目录 1 gcc编译过程 1 1预处理 1 2编译 1 3汇编 1 4链接 2 自动化构建工具 make和makefile 2 1使用背景 2 2两者的概念和区别 2 3项目清理 3 Linux简单进度条的实现 1 gcc编译过程 1
  • ubuntu安装qt

    ubuntu安装qt 第一步 下载安装包https download qt io archive qt 5 14 5 14 2 第二步 更改权限 sudo chmod x qt opensource linux x64 5 12 12 ru
  • JS中使用正则表达式g模式和非g模式的区别

    g是global的缩写啊 就是匹配全部可匹配结果 如果你不带g 在正则过程中 字符串是从左至右匹配的 如果匹配成功就不再继续向右匹配了 如果你带g 它会重头到尾的把正确匹配的字符串挑选出来 例如 1 2 3 4 5 var str aaaa
  • C++ std::vector删除元素的几种方式及区别

    容器vector在删除过程中 常用的函数 函数 作用 pop back 删除 vector 容器中最后一个元素 该容器的大小 size 会减 1 但容量 capacity 不会发生改变 erase iter 删除 vector 容器中ite