【问题标题】:Alternatives to vector.size() after running remove_if()运行 remove_if() 后替代 vector.size()
【发布时间】:2019-02-13 17:18:32
【问题描述】:

我正在编写一段 C++ 来检查向量的特定元素是否返回 true,如果不是,则使用 remove_if() 删除它们。之后,我使用vector.size()检查向量中是否还有元素,如果没有则返回函数。

目前,我在remove_if() 之后执行vector.erase(),因为它实际上并没有减小向量的大小。但是,此代码需要快速运行,并且递归地更改内存中向量的大小可能并不理想。但是,如果向量为零则返回(而不是运行函数的其余部分)也可能会节省时间。

有没有一种很好的方法来检查向量中剩余多少元素而不擦除?

代码如下:

  auto remove = remove_if(sight.begin(), sight.end(), [](const Glance *a) {
    return a->occupied;
  }); 

  sight.erase(remove, sight.end());

  if (sight.size() == 0) {
    // There's nowhere to move
    return;
  }

编辑: 感谢您的帮助+指导。从答案中可以清楚地看出,问题的措辞并不完全正确:erase() 不会改变内存中向量的大小,而是改变容量。我记错了this post 的解释,这很好地解释了为什么erase() 在多次删除时比remove() 慢(因为您必须多次复制向量中元素的位置)。

我使用 Instruments 来针对 Johannes 的建议对我最初的代码进行基准测试,虽然 Johannes 的速度始终稍快一些(约 9.8% 的权重与约 8.3% 的相同代码的权重),但差异很小。链接的文章应该解释原因。 ✨

【问题讨论】:

  • std::distance(sight.begin(), remove); 会告诉你有多少元素留在“有效”范围内。
  • 请注意,erase 不会导致向量的 容量 改变,没有内存重新分配。
  • 这真的取决于你到底要做什么,但remove - sight.begin() 会告诉你向量中“剩下”了多少元素。
  • 如果您只是在此处存储一个指针,则无需担心速度方面的问题。除了不要使用size() 来测试是否为空,使用empty()
  • 反对这个问题的人能否详细说明原因。我发现这个问题清晰且相关。

标签: c++


【解决方案1】:

可以使用std::distance(sight.begin(), remove);获取剩余元素个数:

auto remove = remove_if(sight.begin(), sight.end(), [](const Glance *a) {
    return a->occupied;
}); 

size_t remaining = std::distance(sight.begin(), remove);

if (remaining == 0) {
    // There's nowhere to move
    return;
}

但如果你只对0感兴趣,你可以这样做:

auto remove = remove_if(sight.begin(), sight.end(), [](const Glance *a) {
    return a->occupied;
}); 

if (remove == sight.begin()) {
    // There's nowhere to move
    return;
}

【讨论】:

    【解决方案2】:

    您可以简单地迭代容器并计算这些元素,而不是删除满足条件的元素,然后检查剩余元素的数量以找出有多少元素不满足条件。标准库有一个算法:std::count_if

    【讨论】:

      猜你喜欢
      • 2012-02-21
      • 2021-09-07
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      相关资源
      最近更新 更多