将向量中的每个项目与其他每个项目进行比较,同时删除一些元素?
Compare every item in a vector to every other item, while deleting some elements?
我需要编写一个函数,将 std::vector<std::shared_ptr<Shape >> shapes_
的每个元素与其他每个元素进行比较,以确定形状是否重叠,然后删除其中一个重叠形状。这是我目前得到的:
class Shape {
public:
...
virtual bool overlaps(const std::shared_ptr<Shape>&) const = 0;
...
};
class Square : public Shape { ... } ;
class Circle : public Shape { ... } ;
并利用这些 类:
std::vector<shared_ptr<Shape>> shapes_;
// ... some code populates the array
for (auto& shape : shapes_) {
// Compare to every other shape
for (unsigned long j = 0; j < shapes_.size(); j++) {
// If they overlap and they aren't the same shape
if (shape->overlaps(shapes_.at(j)) && shape!=shapes_.at(j)) {
shapes_.erase(shapes_.begin() + j);
}
}
}
但是,我一直 运行 遇到问题,在这些问题中,我正在遍历空(已删除)元素,或者超出数组末尾或其他内容。我一直以这种或另一种方式重新配置它,但其中一个问题不断出现。
当您将向量的每个元素与其他所有元素进行比较,并且在这个过程中有时会删除一些元素时,什么是处理问题的最明智、最简洁的方法?
此外,如果我想打印关于找到的每个重叠以及删除的形状的一些信息怎么办?
你可以使用erase-remove成语:
auto it = vec.begin();
auto end = vec.end();
while( std::distance( it, end ) > 1 ) {
auto condition = [shape=*it]( const auto &other ) { return shape->overlaps( other ); };
end = std::remove_if( ++it, end, condition );
}
vec.erase( end, vec.end() );
此 lambda 语法需要 C++14,但如有必要,可以轻松修改它以使用 C++11(例如,通过在 lambda 之前引入临时变量 shape
,或捕获 it
按值 非引用 ).
我需要编写一个函数,将 std::vector<std::shared_ptr<Shape >> shapes_
的每个元素与其他每个元素进行比较,以确定形状是否重叠,然后删除其中一个重叠形状。这是我目前得到的:
class Shape {
public:
...
virtual bool overlaps(const std::shared_ptr<Shape>&) const = 0;
...
};
class Square : public Shape { ... } ;
class Circle : public Shape { ... } ;
并利用这些 类:
std::vector<shared_ptr<Shape>> shapes_;
// ... some code populates the array
for (auto& shape : shapes_) {
// Compare to every other shape
for (unsigned long j = 0; j < shapes_.size(); j++) {
// If they overlap and they aren't the same shape
if (shape->overlaps(shapes_.at(j)) && shape!=shapes_.at(j)) {
shapes_.erase(shapes_.begin() + j);
}
}
}
但是,我一直 运行 遇到问题,在这些问题中,我正在遍历空(已删除)元素,或者超出数组末尾或其他内容。我一直以这种或另一种方式重新配置它,但其中一个问题不断出现。
当您将向量的每个元素与其他所有元素进行比较,并且在这个过程中有时会删除一些元素时,什么是处理问题的最明智、最简洁的方法?
此外,如果我想打印关于找到的每个重叠以及删除的形状的一些信息怎么办?
你可以使用erase-remove成语:
auto it = vec.begin();
auto end = vec.end();
while( std::distance( it, end ) > 1 ) {
auto condition = [shape=*it]( const auto &other ) { return shape->overlaps( other ); };
end = std::remove_if( ++it, end, condition );
}
vec.erase( end, vec.end() );
此 lambda 语法需要 C++14,但如有必要,可以轻松修改它以使用 C++11(例如,通过在 lambda 之前引入临时变量 shape
,或捕获 it
按值 非引用 ).