如何从排序向量中有效地删除一个值?

2023-12-10

假使,假设vec是可移动和可复制对象的排序向量。删除所有匹配元素的最有效方法是什么value?

这是正确且最有效的方法吗?

auto lb = std::lower_bound(vec.begin(), vec.end(), value);
vec.erase(lb, std::upper_bound(std::next(lb), vec.end(), value));

复杂程度如何? (考虑到擦除后所需的任何移动)。


我已经使用四种不同的从排序容器中擦除的方法进行了一些简短的测试。

void erase_v1(std::vector<int> &vec, int value)
{
    vec.erase(std::remove(std::begin(vec), std::end(vec), value), std::end(vec));
}

void erase_v2(std::vector<int> &vec, int value)
{
    auto lb = std::lower_bound(std::begin(vec), std::end(vec), value);
    if (lb != std::end(vec) && *lb == value) {
        auto ub = std::upper_bound(lb, std::end(vec), value);
        vec.erase(lb, ub);
    }
}

void erase_v3(std::vector<int> &vec, int value)
{
    auto pr = std::equal_range(std::begin(vec), std::end(vec), value);
    vec.erase(pr.first, pr.second);
}

// Surt's code, doesn't preserve sorted order
void erase_v4(std::vector<int> &vec, int value)
{
    // get the range in 2*log2(N), N=vec.size()
    auto bounds = std::equal_range(vec.begin(), vec.end(), value);

    // calculate the index of the first to be deleted O(1)
    auto last = vec.end() - std::distance(bounds.first, bounds.second);

    // swap the 2 ranges O(equals) , equal = std::distance(bounds.first, bounds.last)
    std::swap_ranges(bounds.first, bounds.second, last);

    // erase the victims O(equals)
    vec.erase(last, vec.end());
}

测试用std::vector10,000,000 个元素,用范围内的随机数填充[0..9],然后排序 (MS Visual C++ 2013)。

擦除值0(容器正面),代表性时间如下:

time=14.3894 size=8999147 // v1, milliseconds and updated container size
time=11.9486 size=8999147 // v2
time=11.5548 size=8999147 // v3
time=1.78913 size=8999147 // v4 (Surt)

Erase 5(容器的中间):

time=12.8223 size=9000844
time=4.89388 size=9000844
time=4.87589 size=9000844
time=1.77284 size=9000844

Erase 9(容器的末端):

time=12.64 size=9000820
time=0.00373372 size=9000820
time=0.00339429 size=9000820
time=1.29899 size=9000820

Erase 13(值不在容器中):

time=11.8641 size=10000000
time=0.002376 size=10000000
time=0.00203657 size=10000000
time=0.00220628 size=10000000

The erase/remove方法总是迭代整个容器并且速度较慢,lower_bound/upper_bound and equal_range多次运行的方法几乎相同。我更喜欢最后一个版本,因为它正确、代码更简单并且打字更少。

编辑:定时苏尔特的代码按要求。它始终保持快速,但代价是不保留排序顺序。

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

如何从排序向量中有效地删除一个值? 的相关文章

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • C# 创建数组的数组

    我正在尝试创建一个将使用重复数据的数组数组 如下所示 int list1 new int 4 1 2 3 4 int list2 new int 4 5 6 7 8 int list3 new int 4 1 3 2 1 int list4
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem
  • Azure函数版本2.0-应用程序blobTrigger不工作

    我有一个工作功能应用程序 它有一个 blob 输入和一个事件中心输出 在测试版中工作 随着最新的更改 我的功能不再起作用 我尝试根据发行说明更新 host json 文件 但它没有引用 blob 触发器 version 2 0 extens
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • Java + SSH + Postgres

    我们正在实施一个大学项目 Java 的拼车服务 我们需要解决一个与 如何管理 postgres 服务器 相关的问题 PostgreSQL 数据库配置在名为 golem 130 136 4 sth 的实验室服务器中 只能通过同一子网 130
  • 关于Scala变量可变性的问题

    我明白那个val关键字确定基础变量是不可变类型 以后不能重新分配 现在我在 scala 编程中遇到了一段 第 3 章 scala 中的后续步骤 用类型参数化数组 它指出 val greetStrings Array String new A
  • 等待光标并禁用 java 应用程序

    我想让用户按下按钮来启动后台线程 当线程正在处理时 我希望发生两件事 1 应显示 WAIT CURSOR 2 应用程序不应响应鼠标事件 根据setCursor 文档 当该组件的 contains 方法针对当前光标位置返回 true 时 将显
  • Swift:无法在某些闭包中分解元组(例如,通过枚举减少)?

    当使用map 和enumerate 时 Swift将分解枚举元组 map enumerate 1 2 3 index element in index element 然而 这似乎不能与额外的闭包参数一起使用 例如 使用reduce red
  • 相同的视图控制器加载两次

    我读过关于这个问题的几篇文章 但没有一个能解决我的问题 我正在编写一个应用程序 我必须单击一个按钮 准备 才能转到以下 ViewController 单击按钮时 它还会在两个视图控制器之间传递数据 问题是 当我单击按钮时 以下 ViewCo
  • ActionView 中的 Yield 魔法是如何发挥作用的?

    I was 看着content for 是如何工作的并观察到block call in the capture erb with buffer方法 它显然神奇地写入了缓冲区变量 然后该变量被修剪 但是 我认为这已被弃用 您可以致电现在 这是
  • 为什么RSA加密用C#和Java返回不同的结果?

    I using 时间 2019 03 17 标签 c RSACryptoServiceProvider JAVA KeyFactory getInstance RSA 密码 我将公钥 指数 模数 作为字节数组从java发送到c 没关系 有相
  • 如何在 dot net core 3.0/3.1 上的 razor 页面中添加区域?

    我想在 core 3 1 中添加区域剃刀页面 但微软文档是为了asp点网核心2 2 他们想要创建一个2020 年 1 月新报告 有人知道如何向核心 3 1 添加区域吗 我在谷歌上搜索了很多 但找不到答案 在 AdminLayout 中 a
  • 如何在SVN中存储配置参数?

    与许多项目一样 我们部署到许多环境 QA UA 开发人员主干等 在 SVN 中存储敏感配置参数的最佳方式是什么 或者 您不应该只在服务器上维护一个较小的未版本化文件 其中包含凭据吗 主要是 我们不想向每个开发人员公开生产凭据 我宁愿提供配置
  • Win10 Powershell - 简单的 If/Elseif 取决于条件顺序?

    我正在尝试编写一个部署脚本来检查操作系统主要版本 然后基于该版本运行命令 我可以抓住它就好 System Environment OSVersion Version Major 但是当我尝试在 if elseif 语句中使用它时 我总是得到
  • 高分辨率移动设备 1080px(Xperia Z 等)的媒体查询

    我正在尝试掌握不同设备的媒体查询 我尝试了我的新索尼 Xperia Z 手机 由于分辨率高 可以以全尺寸网站格式显示 如何添加媒体查询来重新调整网格大小和格式 如标准手机比例 在 Xperia 上 字体也太小而无法阅读 需要显示得更大 对于
  • 为什么需要“string DB 20, 22 dup('?')”中的“20, 22”?

    我一直用 for 定义字符串DB 20 22有一段时间不知道为什么 我读到第一个字节是缓冲区大小 第二个字节保存字符串使用的字节数 但我不知道这两个值是否都是强制性的 例如 当我定义一个字符串并想要将寄存器指向它时 我必须使用 2 来跳过这
  • 关于在需要常量表达式的上下文中使用左值常量表达式的问题

    include
  • Spring Boot 应用程序 - 服务器上下文路径

    我使用 Spring Initializer 嵌入式 Tomcat Thymeleaf 模板引擎生成了一个 Spring Boot Web 应用程序 并将其打包为可执行 JAR 文件 使用的技术 Spring Boot 2 0 0 M6 J
  • 即使安装 m2e + DWM 后,Eclipse Indigo SR2 EE 中也没有 Maven 菜单项

    我已经安装了 Eclipse Indigo SR2 EE Eclipse Java EE IDE for Web Developers Version Indigo Service Release 2 Build id 20120216 1
  • 我应该信任哪个编译器?

    这将是一个新手问题 但我正在尝试做一个小练习C语言 不C 我遇到了一些问题 假设我想在方法中使用数组 其大小取决于参数之一 void someFunc int arSize char charArray arSize DO STUFF 当我
  • 抛出或尝试捕获

    决定是否添加时的一般经验法则是什么throws方法的子句或使用try catch 从我自己读到的内容来看 throws当调用者破坏了契约 传递的对象 并且try catch当在方法内部执行的操作期间发生异常时应使用 它是否正确 如果是这样
  • 根据 WooCommerce 中其他运输方式的可用性隐藏运输方式

    我试图根据其他运输方式 通过其 ID 的可用性来隐藏运输方式 以实现稍微复杂的运输设置 根据我发现的其他代码片段 对于其他用例 排除州或仅显示免费送货 如果有 我想出了这个 function hide duplicate shipping
  • 具有不同对象的 TableView (javafx)

    我目前正在开发一个应用程序 用于观察谁负责不同的患者 但是我无法解决如何用不同的对象类型填充表格的问题 下面是我的 TableView 控制器的代码 UITableView 最终将有四种不同的对象类型 所有对象类型都将从数据库中检索 我希望
  • 如何从排序向量中有效地删除一个值?

    假使 假设vec是可移动和可复制对象的排序向量 删除所有匹配元素的最有效方法是什么value 这是正确且最有效的方法吗 auto lb std lower bound vec begin vec end value vec erase lb