跟我学C++中级篇——STL的中的删除
一、介绍
在STL中一般删除的方式有两类,一种是使用全局的std::remove(remove_if类似),一种是使用容器自带的erase,前者其实并没有真正的删除数据,而后者则是在移动时,会有一些细节的处理,否则要么程序崩溃,要么达不到删除的目的。下面就这两个函数进行一下分析说明。
在一些容器中也提供了remove(如std::list)方法,它和全局的std::remove还是用法区别不小的,这个大家需要自己看一下。
注:C++20提供了std::erase这种更方便的用法
二、std::remove和 erase
1、std::remove
它的定义很简单:
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );(C++20 前)
template< class ForwardIt, class T >
constexpr ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class T >
ForwardIt remove( ExecutionPolicy&& policy,ForwardIt first, ForwardIt last, const T& value );
其功能是实现删除在迭代器指定的范围内的所有满足条件的元素并返回尾后迭代器。需要说明的,这里的删除并未真正删除,只是移动,可以在下面的例程中看到相关的示例代码。
2、erase
看一下vector中的定义:
iterator erase( iterator pos );(until C++11)
iterator erase( const_iterator pos );(since C++11)(until C++20)
constexpr iterator erase( const_iterator pos );(since C++20)(2)
iterator erase( iterator first, iterator last );(until C++11)
iterator erase( const_iterator first, const_iterator last );(since C++11)(until C++20)
constexpr iterator erase( const_iterator first, const_iterator last );(since C++20)
它的定义很明显,有两种用法,一种是删除指定位置的元素,一种是删除指定范围的元素。这次之所以总结一下,就是因为发现错误的删除方式不再崩溃。所以得到的结论是,有时崩溃,有时不崩溃,看环境。
3、二者混合
其实就是移动并删除被删除的元素,有点拗口。就是将remove移动后的元素,不再使用的空间内的元素真正删除并和迭代器等自然挂钩。看下面的例子就会明白。
三、例程
例程是以std::vector做为例程的,其它的容器可能细节上会有一些差别,但总体上的应用是一致的。感兴趣可以把其它的几个容器都试一下。
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
#include <vector>void testErase2() {std::vector<int> vec{1, 5, 2, 2, 3, 4, 2, 5, 6, 8, 9, 12};vec.erase(vec.begin() + 9, vec.end());std::cout << "cur vec:";for (auto &d : vec) {std::cout << d << ",";}std::cout << std::endl;
}
void testRemoveErase() {std::vector<int> vec{1, 5, 2, 2, 3, 4, 2, 5, 6, 8, 9, 12};auto it = std::remove(vec.begin(), vec.end(), 2);for (auto beg = it; beg != vec.end(); beg++) {std::cout << *beg << "---" << std::endl;}for (auto beg = vec.begin(); beg != vec.end(); beg++) {std::cout << *beg << "---" << std::endl;}vec.erase(it, vec.end());std::cout << "cur vec:";for (auto &d : vec) {std::cout << d << ",";}std::cout << std::endl;
}
void testDelVec() {std::vector<int> vec{1, 5, 5, 4, 5, 6};std::cout << "vec size:" << vec.size() << std::endl;for (auto it = vec.begin(); it != vec.end();) {if (*it == 5) {it = vec.erase(it);//vec.erase(it);//在Ubuntu22,Qt环境,不崩溃std::cout << "delete it:" << *it << std::endl;} else {it++;}}std::cout << "delete it end" << std::endl;std::cout << "delete it end vec value:" << std::endl;for (auto &d : vec) {std::cout << d << ",";}std::cout << std::endl;
}
void testVec() {std::vector<int> vec{1, 5, 5, 4, 5, 6};auto iter = std::remove(vec.begin(), vec.end(), 5);std::cout << "size is :" << vec.size() << std::endl;std::cout << "capacity is :" << vec.capacity() << std::endl;for (auto first = vec.begin(); first < iter; ++first) {std::cout << *first << " ";}return;
}
void testStr() {std::string test_str = "My test this delete ORC";auto it = std::remove(test_str.begin(), test_str.end(), ' ');std::cout << test_str << std::endl;auto x = test_str.erase(it, test_str.end());std::cout << "test_str:" << test_str << std::endl;
}
int main() {testErase2();testRemoveErase();testDelVec();testVec();testStr();return 0;
}
另外还有一些不太标准的删除方式,如使用resize()函数等,一般不推荐,不过在某些场合下,可能会用着更方便。实际场景决定实际开发的代码吧,不要刻意追求某种方法。
四、总结
之所以把STL中的删除分析一下,是因为早期的印象是只要使用循环遍历的方式(不处理迭代器)暴力删除容器内容一定会崩溃,可现在发现在g++中其实是不崩溃的,把这两个和删除相关的函数就写了个程序跑了一下,给大家一个借鉴。没有什么难度,重点是细节要弄清楚。
相关文章:
跟我学C++中级篇——STL的中的删除
一、介绍 在STL中一般删除的方式有两类,一种是使用全局的std::remove(remove_if类似),一种是使用容器自带的erase,前者其实并没有真正的删除数据,而后者则是在移动时,会有一些细节的处理,否则要么程序崩溃…...
js如何遍历查询一个颗树
近段时间去面试的时候,被面试官问到如何遍历查询一个颗树的时候,可能最近自己看了数据结构的书之后,隐隐约约就想到二叉树的三种排序(前序、中序、后序),但是当时自己没有想起这三种排序的名字,…...
【面试必备】针对一个案例,怎么测试
思考角度 测试用例设计万能公式功能测试(最重要)界面测试易用性测试性能测试安全性测试兼容性测试容错性测试 常见案例物品类水杯笔 软件类微信发送朋友圈功能 测试用例设计万能公式 在面试中经常会遇到的一类题是,给你一个具体的产品&#…...
vue3 hooks之事件广播(支持跨标签页)
/**** 同源下的全局事件总线,支持跨标签页通信* 第一步:注册事件* 第二步:广播事件* 第三步:处理事件*/// source:消息发起源href,将在跨标签页通信时传入 interface callback {(data: any, source: any): …...
go中validate包使用教程
文章目录 前言安装简单使用错误处理翻译器Validator库介绍校验语法常用标记自定义校验需求【校验车身颜色】前言 在go项目中,经常有校验数据合法性的需求,比如邮箱、年龄、车牌号、网址、字符串长度、金额、枚举范围等。一个好的校验包能帮我们少写很多ifelse,提高系统的可…...
canvas画带透明度的直线和涂鸦
提示:canvas画线 文章目录 前言一、带透明度的直线和涂鸦总结 前言 一、带透明度的直线和涂鸦 test.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content…...
linux命令 curl忽略https证书
curl https://www.baidu.com 会提示需要htttps证书,加 -k 即可,如下: curl -k https://www.baidu.com 如果要带头部,认证数据,加-H curl -s -k -H "Authorization: Bearer 651fasgassssgjage2" https:/…...
游戏引擎中网络游戏的基础
一、前言 网络游戏所面临的挑战: 一致性:如何在所有的主机内都保持一样的表现可靠性:网络传输有可能出现丢包安全性:反作弊,反信息泄漏。多样性:不同设备之间链接,比如手机,ipad&a…...
ES6(ECMAScript 6)中常用的知识点总结(包含示例代码)
ES6(ECMAScript 6)是JavaScript语言的最新版本,它在ES5的基础上做了很多增强和扩展,使JavaScript的编程模式更加现代化和优雅,不仅拓展了语言表达能力,也为编程带来了全新的编程范式和思维方式。在项目中使用ES6,让代码更加简洁、方便模块化和面向对象实现等&#x…...
老师人手必备的教学神器有哪些?这5款教学软件一定要知道!
教师职业生活中有哪些“神器”?对老师来说堪称神器的东西有很多,笔者虽不是老师,工作内容有所不同,但工作给人带来的心力消耗(心累/压力/焦虑)、身体上的疲惫(困)等等,这…...
华为机试题-核酸检测人数
题目 为了达到新冠疫情精准防控的需要,为了避免全员核酸检测带来的浪费,需要精准圈定可能被感染的人群。现在根据传染病流调以及大数据分析,得到了每个人之间在时间、空间上是否存在轨迹的交叉。现在给定一组确诊人员编号 (X1, X2, X3, …, n…...
SQLAlchemy模型映射提示declarative_base() takes 0 positional arguments but 1 was given
原码: #SQLAlchemy模型映射表结构. from sqlalchemy import create_engine,Column,Integer,String from sqlalchemy.ext.declarative import declarative_base# 数据库的变量 HOST 127.0.0.1 PORT 3306 DATA_BASE itbz USER root PWD 123456 DB_URL fmysqlpy…...
linux系统Kubernetes工具ingress暴露服务
Ingress Ingressingress详解创建 Ingress 资源部署 Ingress 控制器(Nginx)下载ingress controller创建ingress-controller测试ingress创建两个应用和service配置ingress转发文件 修改ingress转发类型 Ingress 暴露服务基于域名的虚拟主机 Ingress 》ing…...
centos2anolis
我的centos7原地升级到anolis7记录 注意:如果是桌面版请先卸载firefox,否则so文件冲突。 参考: CentOS 7和8Linux系统迁移到国产Linux龙蜥Anolis OS 8手册_disable pam_pkcs11 module in pam configuration-CSDN博客 关于 CentOS 迁移龙蜥…...
Cesium安装部署运行
目录 1.简介 2.Cesium项目下载 3.Cesium项目运行 4.cesium运行 1.简介 Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎。Cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区域,并提供良好的触摸支持,且支…...
【Android 内存优化】KOOM线程泄漏监控的实现源码分析
文章目录 线程monitor的流程怎么判断线程是否泄漏AddThreadJoinThreadExitThreadDetachThread 总结 前面我们通过研究KOOM的开源代码,研究了关于Java层和native层内存泄漏监控的实现原理。还剩下线程泄漏这部分没有进行分析,今天来补全它。整体下来&…...
【爬虫基础】第1讲 网络爬虫基本知识
什么是网络爬虫 网络爬虫(Web crawler)是一种自动化程序,用于在互联网上收集信息。它可以通过扫描和解析网页的超链接,自动访问网页并抓取所需的数据。网络爬虫常用于搜索引擎和数据采集工具中。 作用 通过有效的爬虫手段批量采…...
scrapy爬虫框架
scrapy爬虫框架 一、scrapy的概念作用和工作流程1、scrapy的概念2、scrapy框架的作用3、scrapy的工作流程(重点)3.1 回顾之前的爬虫流程3.2 改写上述流程3.3 scrapy的流程3.4 scrapy的三个内置对象3.5 scrapy中每个模块的具体作用 二、scrapy的入门使用1…...
【深度学习】基础知识
吴恩达DeepLearning Python # 1.numpy c c.ravel() 将多维数组拉平 # 2.time tic time.time() toc time.time() print(str(1000*(toc- tic))"ms")...
Electron应用自动更新实现及打包部署全攻略
Electron应用自动更新实现及打包部署全攻略 Electron自动更新原理配置更新服务器打包与发布更新全攻略实战步骤部署与测试部署更新测试更新流程错误处理与调试 高级特性与优化用户体验与反馈安全与隐私保护维护与持续集成性能优化结语 在现代跨平台桌面应用开发领域中ÿ…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
