根据谓词从std向量中删除元素的有效方法

时间:2013-05-21 17:21:23

标签: c++ c++11 stl

我正在编写一个算法,该算法应该从存储在向量内的一组点中删除每个元素,这些元素位于我提供的任何rect列表中。

我也在使用它作为C ++ 11的测试基础,所以,由于我仍然习惯于新功能,我想知道这是否是一种有效的方法,或者它是否有一些特殊的缺陷,我没有。

vector<tuple<u16, u16, u16, u16>> limits;

FOR_EACH_AREA_TO_REMOVE
   limits.push_back(make_tuple(
       area->x - VIEWPORT_SIZE_X/2, 
       area->x + VIEWPORT_SIZE_X/2, 
       area->y - VIEWPORT_SIZE_Y/2, 
       area->y + VIEWPORT_SIZE_Y/2));
FOR_EACH_AREA_TO_REMOVE_END

vector<Point2D> points;

remove_copy_if(suitablePoints.begin(), suitablePoints.end(), 
               points.begin(), [&](const Point2D &point) {
  for (auto limit : limits)
    if (point->x > get<0>(limit) && 
        point->x < get<1>(limit) && 
        point->y > get<2>(limit) && 
        point->y < get<3>(limit))
      return true;

  return false;
  }
);

这似乎是解决问题的更简单的方法,创建一个必须从点集中排除的边界向量,然后迭代设定点。我想知道是否有更好的解决方法。我想指出的是,这一系列的点数可能很大,而一系列的数量确实足够有限。

1 个答案:

答案 0 :(得分:3)

您可以将auto更改为auto const&,因为您在迭代整个集合时无需在limits中创建每个矩形的副本:

for (auto const& limit : limits)
//        ^^^^^^

这应该会带来一些性能提升(但是就性能而言,一如既往地在得出任何结论之前进行测量)。

此外,除非您需要创建从向量中删除的元素的副本(问题文本未提及此内容),否则您可以使用std::remove_if()代替std::remove_copy_if()

std::remove_if()通过用随后的元素覆盖已删除的元素来工作,并且将返回向量的新逻辑末端而不实际调整向量本身(如果您不需要这样做,这是一种理想的行为)。

因此,std::remove_if()之后调用std::vector::erase()是否要执行此操作。这是a very common practice which also has a name