【问题标题】:Compare every item in a vector to every other item, while deleting some elements?将向量中的每个项目与其他所有项目进行比较,同时删除一些元素?
【发布时间】:2017-12-07 18:12:42
【问题描述】:

我需要编写一个函数,将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);
        }
    }
}

但是,在迭代空(已删除)元素或超出数组末尾或其他内容时,我一直遇到问题。我一直以这种或其他方式重新配置它,但这些问题之一不断出现。

当您将向量的每个元素与其他所有元素进行比较,并且在此过程中有时会删除一些元素时,什么会被认为是处理问题的最明智、最干净的方法?

另外,如果我想打印一些关于找到的每个重叠的信息,以及被移除的形状怎么办?

【问题讨论】:

    标签: c++ loops vector polymorphism shared-ptr


    【解决方案1】:

    你可以使用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 不参考)。

    【讨论】:

    • 一个问题:它会删除所有元素,因为它会尝试在第一次循环迭代时检查与自身的重叠。你想在这里预增量。
    • 谢谢,我会调查一下,我最终需要打印一些关于每个重叠(哪两个形状重叠)以及哪个形状被删除的信息。我会把它放在 lambda 体内吗?
    • @transiti0nary 是的,当然你可以把它放在 lambda 中,或者你可以在擦除之前迭代 end, vec.end() 范围。
    • 谢谢,现在可以正常工作了! Lambda 对我来说仍然有点神秘,所以我从来没有想过这个
    • @transiti0nary 它不必是 la​​mbda,您可以使用仿函数或任何函数(如果签名不匹配,则使用 std::bind)。使用 lambda 更简单。
    猜你喜欢
    • 2011-06-27
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    相关资源
    最近更新 更多