0

0

C++ 怎么删除vector元素 C++ erase函数与remove算法结合用法【容器】

穿越時空

穿越時空

发布时间:2026-01-25 12:05:02

|

198人浏览过

|

来源于php中文网

原创

vector::erase 删除单个或连续元素时应避免边遍历边用递增下标删除,正确做法是使用迭代器删除后接收返回值,或逆向遍历、标记+erase-remove惯用法。

c++ 怎么删除vector元素 c++ erase函数与remove算法结合用法【容器】

vector::erase 删除单个或连续元素时的正确姿势

直接调用 erase 是最直观的删除方式,但它会移动后续所有元素,时间复杂度是 O(n)。删末尾最快,删开头或中间代价高。

常见错误是边遍历边 erase 还用递增下标,导致跳过下一个元素:

for (size_t i = 0; i < v.size(); ++i) {
    if (v[i] == 42) v.erase(v.begin() + i); // ❌ 错!i 自增后指向原 i+2 位置
}

正确做法是使用返回的迭代器(erase 返回删除位置之后的合法迭代器):

for (auto it = v.begin(); it != v.end(); ) {
    if (*it == 42) it = v.erase(it); // ✅ 返回新 it,不自增
    else ++it;
}
  • erase(pos) 删除单个元素,返回后继迭代器
  • erase(first, last) 删除区间,返回 last
  • 删除后所有指向被删元素及之后的迭代器、引用、指针全部失效

为什么不能只用 std::remove?它根本没删元素

std::remove 是个“逻辑删除”算法:它把不满足条件的元素前移,返回一个新逻辑终点迭代器,但容器大小不变,后面是未定义值(通常是原尾部残留)。

立即学习C++免费学习笔记(深入)”;

典型误用:

Gaga
Gaga

曹越团队开发的AI视频生成工具

下载
std::remove(v.begin(), v.end(), 42); // ❌ 容器 size 没变,数据没真删
// 此时 v 可能变成 {1,2,3,1,2,3,?, ?, ?},? 是脏数据

必须配合 erase 才算真正删除(即“erase–remove 惯用法”):

v.erase(std::remove(v.begin(), v.end(), 42), v.end()); // ✅ 真删
  • std::remove 是稳定算法,保持剩余元素相对顺序
  • 只适用于可赋值类型,且比较用 ==
  • vector 来说,它比多次 erase 快得多(一次移动,O(n);多次 erase 是 O(n²))

删除满足任意条件的元素:用 remove_if + lambda

当删除逻辑不是简单相等(比如删偶数、删空字符串、删超时对象),就得用 std::remove_if

v.erase(std::remove_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; }), v.end());

注意 lambda 捕获和生命周期:如果要访问外部变量(如阈值、容器引用),需显式捕获,避免悬垂引用。

  • lambda 中不要修改容器本身,否则行为未定义
  • 若条件判断开销大,可提前计算缓存,避免重复调用
  • 对自定义类型,确保 operator== 或谓词逻辑正确,尤其注意 const 成员函数修饰

性能与安全边界:vector 删除的隐藏成本

频繁在头部或中部删除,vector 不是最佳选择——每次 erase 都触发大量内存拷贝。此时应考虑 std::liststd::deque(后者支持高效首尾删,但中部删仍慢)。

另一个易忽略点:erase 后立即访问 v.back()v[v.size()-1] 前,务必检查 v.empty(),否则越界未定义行为。

  • 释放内存?erase 不改变容量(v.capacity() 不变),要用 shrink_to_fit() 提议释放(不保证执行)
  • 多线程下,eraseremove 都非线程安全,需外部同步
  • std::unique 去重时,必须先排序,否则只删相邻重复项

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

527

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

278

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1493

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

622

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

572

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

586

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

168

2025.07.29

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

45

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 7.5万人学习

C 教程
C 教程

共75课时 | 4.2万人学习

C++教程
C++教程

共115课时 | 13.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号