C++ std::remove/std::remove_if/erase用法探讨

​std::remove 不会改变输入vector/string的长度。其过程相当于去除指定的字符,剩余字符往前靠。后面的和原始字符保持一致。​

需要注意的是,remove函数是通过覆盖移去的,如果容器最后一个值刚好是需要删除的,则它无法覆盖掉容器中最后一个元素(具体可以看下图执行结果),相关测试代码如下:

#include "stdafx.h"
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
#include <ctime>using namespace std;void ShowVec(const vector<int>& valList)
{for (auto val : valList){cout << val << " ";}cout << endl;
}bool IsOdd(int i) { return i & 1; }int main()
{vector<int> c = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 8, 7, 6, 5, 4, 3, 2, 1};cout << "current v_size: " << c.size() << endl;ShowVec(c);remove(c.begin(), c.end(), 1);cout << "after remove, v_size: " << c.size() << endl;ShowVec(c);c.erase(std::remove(c.begin(), c.end(), 2), c.end());cout << "after erase remove 1, v_size: " << c.size() << endl;ShowVec(c);c.erase(std::remove_if(c.begin(), c.end(), IsOdd), c.end());cout << "after erase remove_if Odd, v_size: " << c.size() << endl;ShowVec(c);vector<int> vct;for (int i = 0; i < 1000000; i++){vct.push_back(i);}clock_t start_time = clock();/*for (vector<int>::iterator it = vct.begin(); it != vct.end();){if (IsOdd(*it)){it = vct.erase(it);}else{++it;}}*/vct.erase(std::remove_if(vct.begin(), vct.end(), IsOdd), vct.end());clock_t cost_time = clock() - start_time;std::cout << " 耗时:" << cost_time << "ms" << std::endl;return 0;
}

执行如下:

如果是注释掉

vct.erase(std::remove_if(vct.begin(), vct.end(), IsOdd), vct.end());

采用erase直接删除指定规则元素,需要注意的是,vector使用erase删除元素,其返回值指向下一个元素,但是由于vector本身的性质(存在一块连续的内存上),删掉一个元素后,其后的元素都会向前移动,所以此时指向下一个元素的迭代器其实跟刚刚被删除元素的迭代器是一样的:

for (vector<int>::iterator it = vct.begin(); it != vct.end();){if (IsOdd(*it)){it = vct.erase(it);}else{++it;}}

执行结果如下:

由此可见,对大数据量的操作,用 vct.erase(std::remove_if(vct.begin(), vct.end(), IsOdd), vct.end()) 比直接用erase,效率提升非常大,算法整体复杂度低。

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

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

相关文章

再谈NULL和nullptr(C++11)区别

在谈NULL和nullptr区别之前&#xff0c;我们先看段代码&#xff1a; #include "stdafx.h" #include <iostream>using namespace std; void func(void *p) {cout << "p is pointer " << p << endl; } void func(int num) {cout &l…

C++11新特性探索:原始字符串字面值(raw string literal)

原始字符串字面值(raw string literal)是C11引入的新特性。 原始字符串简单来说&#xff0c;“原生的、不加处理的”&#xff0c;字符表示的就是自己&#xff08;所见即所得&#xff09;&#xff0c;引号、斜杠无需 “\” 转义&#xff0c;比如常用的目录表示&#xff0c;引入…

Android国标接入终端实现GB28181实时位置(MobilePosition)上报

技术背景 在实现本文提到的Android平台国标GB28181接入终端的实时位置上报之前&#xff0c;之前已经完成了Android终端GB28181常规功能接入&#xff0c;采集到实时音视频数据&#xff0c;编码PS打包后&#xff0c;按需传到GB28281服务平台&#xff0c;媒体流支持最新GB28181-2…

基于RTMP的智慧数字人|AI数字人传输技术方案探讨

技术背景 随着智慧数字人、AI数字人的兴起&#xff0c;越来越多的公司着手构建​全息、真实感数字角色等技术合成的数字仿真人虚拟形象&#xff0c;通过“虚拟形象语音交互&#xff08;T-T-S、ASR&#xff09;自然语言理解&#xff08;NLU&#xff09;深度学习”&#xff0c;构…

​GB28181心跳机制探讨和技术实现

​GB/T 28181-2016心跳机制​ ​通过周期性的状态信息报送&#xff0c;实现注册服务器与源设备之间的状态检测即心跳机制。 ​ ​心跳发送方、接收方需统一配置“心跳间隔”参数&#xff0c;按照“心跳间隔”定时发送心跳消息&#xff0c;默认心跳间隔60s。心跳发送方、接收方…

Unity3D下Linux平台播放RTSP或RTMP流

背景 尽管Windows平台有诸多优势&#xff0c;Linux平台的发展还是势不可挡&#xff0c;特别实在传统行业&#xff0c;然而Linux生态构建&#xff0c;总是差点意思&#xff0c;特别是有些常用的组件&#xff0c;本文基于已有的Linux平台RTSP、RTMP播放模块&#xff0c;构建Unit…

Unity3D平台实现全景实时RTMP|RTSP流渲染

好多开发者的使用场景&#xff0c;需要在Windows特别是Android平台实现Unity3D的全景实时视频渲染&#xff0c;本文以Windows平台为例&#xff0c;简单介绍下具体实现&#xff1a; 如果是RTSP或RTMP流数据&#xff0c;实际上难点&#xff0c;主要在于拉取RTSP或RTMP流&#xf…

C++17新特性之std::string_view

std::string_view系C17标准发布后新增的内容&#xff0c;类成员变量包含两个部分&#xff1a;字符串指针和字符串长度&#xff0c;相比std::string, std::string_view涵盖了std::string的所有只读接口。如果生成的std::string无需进行修改操作&#xff0c;可以把std::string转换…

Android平台实现RTSP|RTMP转GB28181网关接入

背景 在事先Android平台RTSP、RTMP转GB28181网关之前&#xff0c;我们已经实现了Android平台GB28181的接入&#xff0c;可实现Android平台采集到的音视频数据&#xff0c;编码后&#xff0c;打包按需发到GB28181服务平台。此外&#xff0c;拉流端&#xff0c;我们已经有了成熟…

Unity3D下实现Linux平台RTMP推流(以采集Unity窗体和声音为例)

技术背景 随着物联网等行业的崛起&#xff0c;越来越多的传统行业如虚拟仿真、航天工业、工业仿真、城市规划等&#xff0c;对Linux下的生态构建&#xff0c;有了更大的期望&#xff0c;Linux平台下&#xff0c;可选的直播推拉流解决方案相对Windows和移动端&#xff0c;非常少…

Android平台实现VR头显Unity下音视频数据RTMP推送

背景 随着技术发展的日新月异&#xff0c;虚拟现实产业已经从过去的探索期&#xff0c;自2020年起&#xff0c;慢慢过渡到高速发展期&#xff0c;随着5G时代的到来&#xff0c;大带宽高可靠低延迟网络环境&#xff0c;为虚拟现实产业提供了很好的网络保障&#xff0c;虚拟现实…

C++11特性之std:call_once介绍

std:call_once是C11引入的新特性&#xff0c;如需使用&#xff0c;只需要#include <mutex>即可&#xff0c;简单来说std:call_once的作用&#xff0c;确保函数或代码片段在多线程环境下&#xff0c;只需要执行一次&#xff0c;常用的场景如Init()操作或一些系统参数的获取…

2022年了,该学C++还是Java?

最近好多朋友私信我&#xff0c;C好不好学&#xff1f;学C好还是Java好&#xff1f; 我的回答是&#xff1a;C不好学&#xff0c;但你觉得C不好学的话&#xff0c;Java也不好学。因为C难是难在语言本身&#xff0c;java难是难在各种框架和库。 C学习进阶比较陡, 对新手不友好&…

Android平台音视频RTMP推送|GB28181对接之动态水印设计

技术背景 随着移动单兵、智能车载、智慧安防、智能家居、工业仿真、GB28281技术对接等行业的发展&#xff0c;现场已经不再限于采集到视频数据编码打包发送或对接到流媒体服务端&#xff0c;大多场景对视频水印的要求越来越高&#xff0c;从之前的固定位置静态文字水印、png水…

探究C++11智能指针之std::unique_ptr

背景 谈起C&#xff0c;它被公认为最难学的编程语言之一&#xff0c;不仅语法知识点广泛&#xff0c;细节内容之多&#xff0c;学习难度和学习周期也长&#xff0c;导致好多新入行的开发者对C“敬而远之”&#xff0c;甚至“从入门到放弃”。自C11开始&#xff0c;好多C程序员…

C++17新特性之try_emplace与insert_or_assign

由于std::map中&#xff0c;元素的key是唯一的&#xff0c;我们经常遇到这样的场景&#xff0c;向map中插入元素时&#xff0c;先检测map指定的key是否存在&#xff0c;不存在时才做插入操作&#xff0c;如果存在&#xff0c;直接取出来使用&#xff0c;或者key不存在时&#x…

Unity环境下实现Camera高帧率RTMP推送

Unity下RTMP直播背景方面不再赘述&#xff0c;今天主要讨论的是&#xff0c;Unity环境下&#xff0c;如何实现Camera高帧率RTMP推送&#xff0c;这里提到的高帧率&#xff0c;不再局限于常规环境下的30帧&#xff0c;以VR头显为例&#xff0c;更高的帧率&#xff08;比如50帧&a…

如何在Android平台GB28181接入终端实现语音广播和语音对讲

技术背景 在之前的blog&#xff0c;我们以Android平台国标接入终端为例&#xff0c;分别介绍了一些常规的功能&#xff0c;比如REGISTER、CATALOG、INVITE、Keepalive、SUBSCRIBE、NOTIFY等常规操作&#xff0c;今天主要介绍下语音广播和语音对讲这部分。 GB28181平台广播和对…

Android GB28181设备接入端语音广播和语音对讲技术实现探究

上篇文章提到Android端GB28181接入端的语音广播和语音对讲的实现&#xff0c;从spec角度大概介绍了下流程和简单的接口设计&#xff0c;好多开发者私信我&#xff0c;希望展开说一下。其实这块难度不大&#xff0c;只是广播和对讲涉及到双向实现&#xff0c;如果之前没有相关的…

Android native层实现MediaCodec编码H264/HEVC

Android平台在上层实现mediacodec的编码&#xff0c;资料泛滥&#xff0c;已经不再是难事&#xff0c;今天给大家介绍下&#xff0c;如何在Android native层实现MediaCodec编码H264/HEVC&#xff0c;网上千篇一律的接口说明&#xff0c;这里不再赘述&#xff0c;本文主要介绍下…