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

2023-10-30

​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,效率提升非常大,算法整体复杂度低。

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

C++ std::remove/std::remove_if/erase用法探讨 的相关文章

  • 这种双重实例是否有害,或者根本没有必要?

    在仔细阅读遗留资源时 我发现了这一点 DataSet myUPC new DataSet myUPC dbconn getDataSet dynSQL Resharper 正确地将其中的 new Dataset 部分 灰显 并建议 删除多余
  • C++,多语言/本地化支持

    向 C 程序添加多语言支持的最佳方法是什么 如果可能 应该从包含键值对 WelcomeMessage Hello s 之类的纯文本文件中读取语言 我想到了添加一个 localizedString key 函数来返回加载的语言文件的字符串 有
  • OpenGL,如何独立旋转对象?

    到目前为止我的代码 void display void glClear GL COLOR BUFFER BIT GL DEPTH BUFFER BIT Clear Screen And Depth Buffer glLoadIdentity
  • 运行 C# exe 文件

    复制 为什么我的 NET 应用程序在从网络驱动器运行时会崩溃 https stackoverflow com questions 148879 why does my net application crash when run from
  • 更新 OSX 命令行工具 6.3 后缺少 C++ 标头 <__debug>

    从 App Store 更新到 Command Line Tools 6 3 后 程序包括
  • const_iterators 更快吗?

    我们的编码指南更喜欢const iterator 因为它们比正常的要快一点iterator 当您使用时 编译器似乎会优化代码const iterator 这真的正确吗 如果是的话 内部到底发生了什么使得const iterator快点 编辑
  • WCF 客户端返回空数组 - XML 响应似乎正常

    我正在尝试为我们的 Intranet 上托管的 Web 服务创建一个简单的 WCF 客户端 C 使用 Fiddler 和 SoapUI 我可以看到请求和响应似乎正常 但是当我运行代码时返回一个空数组 我会尝试只粘贴相关的行 但会是很多东西
  • 泛型类上的 DebuggerDisplay

    我在应用时遇到问题DebuggerDisplay泛型类的属性 DebuggerDisplay foo class Foo DebuggerDisplay Bar t class Bar
  • 如何在C中递归地找到另一个字符串中的字符串位置?

    我们有一个任务来创建带有两个字符串参数的递归函数 原型应该是这样的 int instring char word char sentence 如果我们愿意调用函数 instring Word Another Word 它应该具有以下返回值
  • 加载配置文件时发生错误:访问路径 c:\Program Files (x86)\... 被拒绝

    我有一个在 Windows 7 上使用 Visual Studio 2010 中的安装程序部署的应用程序 该程序在 Windows 7 和 XP 上部署并运行良好 但当我在 Windows 8 系统上部署它时 出现有关访问配置文件的错误 该
  • 将数字 n 拆分为 k 个不同数字的总和

    我有一个数字 n 我必须将它分成 k 个数字 使得所有 k 个数字都是不同的 k 个数字的总和等于 n 并且 k 最大 例如 如果 n 为 9 则答案应为 1 2 6 如果 n 为 15 则答案应为 1 2 3 4 5 这就是我尝试过的 v
  • 通过 MVC 将数据写入数据库的最佳方法是什么?

    我正在使用 MVC 和 EF Core 开发一个家庭作业项目 我正在寻找将数据写入数据库的最佳方法 我是初学者 有两张桌子 Predbilje ba 报名 和Seminari 研讨会 public class Predbilje ba Ke
  • 如何将此 Boost ASIO 示例应用到我的应用程序中

    我已经阅读了很多 ASIO 示例 但我仍然对如何在我的应用程序中使用它们感到困惑 基本上 我的服务器端需要接受超过100个连接 客户端 这部分是通过使用线程池 通常每个CPU核心2 4个线程 来完成的 为简单起见 我们假设只有一个连接 为了
  • 仅最后一个用户控件显示内容控件

    我有一个奇怪的问题 我创建了一个带有标签和画布的用户控件 画布引用资源 但画布仅显示在我的堆栈面板中的最后一个控件上 这是我的窗户
  • 使用 System.Json 迭代 JSON

    我正在探索 NET 4 5 的功能System Json库 但没有太多文档 而且由于流行的 JSON NET 库 搜索起来相当棘手 我基本上想知道 我如何循环一些 JSON 例如 People Simon Age 25 Steve Age
  • Lambda 按值捕获和“mutable”关键字

    关键词的必要性mutable在 lambda 中 是造成极大混乱的根源 考虑代码 int x 10 function
  • 在运行时将项目添加到 ToolStrip

    您好 我有一个带有 收藏夹 菜单的 ToolStripMenu 我想在运行时在 WinForms 应用程序中添加子项目 我有一个 datagridview 右键单击它会显示一个包含 添加到收藏夹 选项的上下文菜单 当该事件被触发时 我想使用
  • 具有两个表的谓词构建器

    A Party可以有一个或多个Contact对象 我想选择全部Parties谁的街道名称包含特定关键字 如果我只想搜索Party我可以使用下面的代码 但我如何扩展它来搜索Contact public IQueryable
  • 恐怖分子已弃用

    正在接听另一个问题 https stackoverflow com q 11830514 1468366 我偶然发现了man page http linux die net man 3 herror一个名为的函数herror 看起来很像pe
  • 使用 Powershell 或 C# 获取 Azure“文件和文件夹”作业状态

    我一直在尝试找到一种方法来获取在 AzureRM 中运行的几个客户上运行的 文件和文件夹 备份作业的状态 可以在 AzureRm 门户中手动找到状态 恢复服务保管库 gt 作业 gt 备份作业 使用powershell不显示任何作业信息 G

随机推荐

  • 【深入理解C++】引用

    文章目录 1 变量的别名 2 变量的多个别名 3 引用存在的价值 4 引用的大小 5 从汇编角度看引用 6 结构体的引用 7 指针的引用 8 数组的引用 1 变量的别名 在 C 语言中 使用指针 Pointer 可以间接获取 修改某个变量的
  • AS3.0(ActionScript3.0)的开发工具

    转自Adobe 根据项目需求和可用资源 您可能希望使用几个工具中的一个 或结合使用多个工具 来编写和编辑 ActionScript 代码 Flash 创作工具除了创建图形和动画的功能之外 Adobe Flash CS3 Profession
  • portal.php无法打开,Discuz论坛为什么门户、论坛都只能访问到门户?论坛无法访问...

    最近无忧主机小编碰到一个非常奇怪的问题 正常情况下 discuz的门户和论坛是可以分开访问的 比如51php com forum php和51php com portal php 分别访问到的是论坛和门户 相信大部分的客户也是这样的 但是昨
  • sqlilabs靶场学习(part1:环境搭建)

    sqlilabs靶场学习 0x00 两个小目标 0x01 sqlilabs 简介 0x02 sqlilabs 环境搭建 1 db creds inc文件配置 2 setup db php文件创建表结构 0x03 测试关卡 0x00 两个小目
  • 架设传奇时打开DBC数据库出错或读取DBC失败解决方法

    架设传奇时打开DBC数据库出错或读取DBC失败解决方法 DBC右键 属性 高级 管理员身份运行 即可 转载于 https www cnblogs com tutublogs p 8136792 html
  • Python函数和模块运用实践

    1 函数的定义与调用 函数名尽量用英文单词命名 并且容易识别意思 函数的形参有4中类型的参数 位置参数 指定参数 缺省参数和不定长参数 在python实践过程中用的最多的是不定长参数 不定长参数方便代码重构 def introduction
  • 使用Clion开发STM32过程中的提示:此文件不属于任何项目目标,代码洞察功能可能无法正常工作(附带汉化方法)

    Catalog 一 问题描述 二 解决办法 三 附带Clion汉化方法 一 问题描述 笔者在学习STM32开发过程中 在使用CubeMX生成工程文件后 又新建了自己的User文件 在编译的过程中终端会提示 在文件中会提示 并且笔者检查代码确
  • SQLite基本操作

    SQLite SQLite是一个软件库 实现了自给自足的 无服务器的 零配置的 事务性的 SQL 数据库引擎 SQLite 源代码不受版权限制 SQLite 直接访问其存储文件 SQLite 是非常小的 是轻量级的 完全配置时小于 400K
  • Git安装与配置

    1 Git安装与配置 1 1 什么是Git Git是目前世界上最先进的分布式版本控制系统 Git是免费 开源的 最初Git是为辅助 Linux 内核开发的 来替代 BitKeeper 作者 Linux和Git之父李纳斯 托沃兹 Linus
  • Java用JDBC通过远程连接PostgreSQL并实现操作

    工具及准备介绍 1 本文使用的开发软件是eclipse1 7 2 需要下载postgresqlpostgresql 9 2 1002 jdbc3 jar 需要的话在我的资源上下载 需要数据库管理软件Navicat 3 本文是用JDBC连接数
  • CSDN中如何转载他人的博客

    1 复制他人博客内容 打开需要转载的博客文章 在页面任意空白处点击鼠标右键 gt 检查 打开浏览器开发模式页面 在元素中找到名为article content的div 选中后右击 gt 复制 gt 复制 outerHTML 2 新写博客文章
  • 理想倍频器/分频器对相噪/杂散的影响

    结论 使用理想倍频器将信号频率提高 N N倍 会让相噪抬高 20log 10 N 20log 10 N dB 类似的 N N分频会让相噪降低 20log 10 N 20log 10 N dB 理想倍频器 对于信号 f t cos t t f
  • Stegsolve.jar工具包准备,避坑指南,教你正确启动Stegsolve

    目录 准备阶段 错误重现 错误分析 Stegsolve jar正确启动方法 准备阶段 下载地址 http www caesum com handbook Stegsolve jar 环境配置的过程 3分钟复制粘贴配置java环境变量 验证配
  • [Unity]有关curson/鼠标的详细AIP

    Unity 有关curson 鼠标的详细AIP 经常用到的与curson有关的API Cursor lockState Cursor lockState CursorLockMode None 光标行为未修改 Cursor lockStat
  • MySQL秘籍:让你的表操作炉火纯青

    每个人都有自己的一生 不要和别人去比较 比较只会让你感到沮丧和不满足 关注自己的成长和进步 并享受属于自己的旅程 作者 不能再留遗憾了 专栏 MySQL学习 本文章主要内容 学习MySQL的对表操作 查看表 创建表 删除表 对表进行增删改查
  • Vue 实现生成二维码(qrcodejs2),并生成图片(html2canvas)可实现保存和识别

    1 引包 npm install qrcodejs2 save npm install save html2canvas import html2canvas from html2canvas import QRCode from qrco
  • 传送文件到云服务器,传送文件到云服务器

    传送文件到云服务器 内容精选 换一换 安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具 将文件上传到云服务器 例如QQ exe 在本地主机和Windows云服务器上分别安装数据传输工具 将文件上传到云服务器 例如QQ e
  • Linux基础笔记4

    绝对路径 以根目录为参照物 从根目录开始 一级一级进入目录 相对路径 以当前目录作为参照物 进行目录查找 1 1 目录操作 ls 显示目录下的内容 查看 etc passwd文件 文件夹下的信息 ls l etc passwd 查看当前文件
  • zookeeper连接,报caught end of stream exception EndOfStreamException: Unable to read additional data fro

    最近发现线上的zookeeper的日志zookeeper out 文件居然有6G 后来设置下日志为滚动输出 但是改了之后 发现一天的日志量就是100多M 滚动日志一天就被冲掉了 这个不科学 再仔细查看下日志里的内容 发现有很多连接建立好 马
  • C++ std::remove/std::remove_if/erase用法探讨

    std remove 不会改变输入vector string的长度 其过程相当于去除指定的字符 剩余字符往前靠 后面的和原始字符保持一致 需要注意的是 remove函数是通过覆盖移去的 如果容器最后一个值刚好是需要删除的 则它无法覆盖掉容器