- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用带有 lambda 谓词的 std::remove_if 同时删除多个元素的最快和最有效的方法是什么?目前我有一个带有位置和唯一 ID 的点结构。在更新循环中,我们填充点 vector ,并在更新循环结束时添加要删除的点。目前,我必须在循环内调用 remove_if 以从点 vector 中删除所有已删除的点。例如,如果我们每帧添加 10 个点,然后循环所有点以检查该点是否在屏幕边界之外,如果它被添加到 deletedPoints_。
struct Point
{
/// Position.
Vector3 position_;
/// Unique id per point
int id_;
}
/// Current max id
int maxId_;
/// All points
std::vector<Point> points_;
/// Deleted points
std::vector<Point> deletedPoints_;
//Updates with 60fps
void App::Update()
{
/// Add 10 points per frame
for (int i = 0; i < 10; ++i)
{
Point newPoint;
/// Add position
newPoint.position_ = worldPosition;
/// Add id starts from 1
maxId_ += 1;
startPoint.id_ = maxId_;
/// Add new point in points
points_.push(newPoint);
}
/// If points outside of screen bounds add them to deletedPoints_
if (points_.size() > 0)
{
for (int i = 0; i < points_.size(); ++i)
{
/// Bounds
Vector2 min = Vector2(0.00,0.00);
Vector2 max = Vector2(1.00,1.00);
/// Check Bounds
if(points_[i].x < min.x || points_[i].y < min.y || points_[i].x > max.x || points_[i].y > max.y)
{
deletedPoints_.push(points_[i]);
}
}
/// Loop deleted points
for (int i = 0; i < deletedPoints_.size(); ++i)
{
int id = deletedPoints_[i].id_;
/// Remove by id
auto removeIt = std::remove_if(points_.begin(), points_.end(),
[id](const TrailPoint2& point)
{ return point.id_ == id; });
points_.erase(removeIt, points_.end());
}
}
}
最佳答案
在不改变结构的情况下,最快的解决方法是反转整个循环并检查 deletedPoints
而不是从 lambda 的内部。
然后,生成deletedPoints
一个std::set<int>
存储您的唯一 ID。那么它会比较快,因为std::set<int>::find
不需要扫描整个容器,尽管您的最终复杂度仍然不是线性时间。
std::vector<Point> points_;
std::set<int> deletedPointIds_;
/// Remove by id
auto removeIt = std::remove_if(points_.begin(), points_.end(),
[&](const TrailPoint2& point)
{ return deletedPointIds_.count(point.id_); });
points_.erase(removeIt, points_.end());
deletedPointIds_.clear();
也就是说,是否切换到 std::set
实际上会更快取决于一些事情;由于 set
的方式,您失去了内存位置并放弃了缓存机会的元素被存储。
另一种方法可能是保留 vector (ID 而不是点!),对其进行预排序,然后使用 std::binary_search
获得快速搜索的好处以及顺序存储数据的好处。但是,执行此搜索可能不适合您的应用程序,具体取决于您拥有多少数据以及您需要多久执行一次此算法。
您也可以使用 std::unordered_set<int>
而不是 std::set
;这与 std::set
有相同的问题但是基于哈希的查找可能比基于树的查找更快。同样,这完全取决于数据的大小、形式和分布。
最终,唯一确定的方法是在模拟范围内尝试一些事情并测量。
关于c++ - 使用带有 lambda 谓词的 std::remove_if 删除多个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43412757/
我有一个弱指针 vector ,如果指针仍然存在,我想遍历该列表并执行一个函数。如果指针不见了,我想将其移除。 class my_class { public: std::shared_ptr
我一直在阅读最新的 C++ 规范,但我无法弄清楚是否可以为同一元素多次调用 remove_if。特别是,我正在查看在 deque 迭代器上调用的 std::remove_if。据我所知,如果它所做的只
我正在尝试从字符串中删除空格。但抛出错误。 我的代码哪个参数做错了..感谢您的查看 我的主要功能 #include #include #include #include #include #
在下面的示例中,我从列表中删除了 pr2 对其应用返回 true 的范围内的一些元素。 m_list.remove_if(pr2(*tmp_list)); 在我看来有必要删除上面删除的这个对象,因为当
如果那些没有修改容器?例如,我想输出我从 vector 中删除的所有整数(我不想使用多次传递:例如:partition + output + erase)。撇开设计恐怖不谈,这是合法的: v.eras
我想删除按引用传递的字符串中的第一个和最后一个括号。不幸的是,我很难有条件地删除第一个和最后一个元素。我不明白为什么 remove_if 不能像我期望的那样使用迭代器。 Demo #include
我想使用 remove_if 函数从 vector 中删除元素,但将删除限制为 N 个元素。 例子: // predicate function that determines if a value
VS2010编译错误: c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1840): error C2
有人可以告诉我如何使用 Remove_If 进行一些不区分大小写的比较吗? 目前我是这样做的: template struct is_literal { enum{value = false};
我正在考虑在下面的伪代码中对字符串 vector 使用 remove_if: for(some strings in a given set) { remove_if(myvec.begin(),
我正在尝试使用 std::remove_if从一个简单的字符串中删除空格,但我得到了奇怪的结果。有人可以帮我弄清楚发生了什么吗? 该代码是: #include #include #include
我的 remove_if 似乎正在用过滤掉的元素的值覆盖未过滤掉的元素。这些代码的目的是允许用户过滤和仅显示某个类别的教师。 (不删除任何元素)下面是部分代码 static string compar
我想知道是否可以使用 remove_if 和 lambda 表达式来表示此表达式。 std::list::iterator astit = actors.begin();
我收到的以下代码的错误消息是: error C2662: 'DamageNumbers::IsAlive' : cannot convert 'this' pointer from 'cons
我正在为具有硬编码最大元素数 N 的数据结构开发一种删除方法,它依赖于 std::array 来避免堆内存。虽然 std::array 只包含 N 个元素,但只有 M 个元素,其中 M 是“相关”元素
我正在尝试从字符串中删除空格 line.erase(remove_if(line.begin(), line.end(), isspace), line.end()); 但是 Visual Studi
我正在尝试使用 remove_if 从 vector 中删除对,但出现错误 bool MyClass::isSingleTag(const pair & val) { string tag =
这里的str是一个string: str.erase(std::remove_if(str.begin(), str.end(), &islower)); 似乎只删除字符串前面的小写字符。为什么会这样
我想知道如何根据条件从列表中删除对象。 经过研究,我得到了这个,但是还是不行! 所以我想知道如何使用带删除的remove_if。 Class A { public: A(int x,int y
我有密码 vector v; v.erase(remove_if(v.begin(),v.end(),bool_checker),v.end()); 其中 v 是一个包含随机数 {2, 4 ,5,
我是一名优秀的程序员,十分优秀!