如何根据另一个向量中的条件从向量中删除元素?

问题描述:

我有两个等长向量,我想根据其中一个向量的条件从中删除元素.应当对两者应用相同的删除操作,以使索引匹配.

I have two equal length vectors from which I want to remove elements based on a condition in one of the vectors. The same removal operation should be applied to both so that the indices match.

我想出了一个使用 std :: erase 的解决方案,但是它非常慢:

I have come up with a solution using std::erase, but it is extremely slow:

vector<myClass> a = ...;
vector<otherClass> b = ...;
assert(a.size() == b.size());
for(size_t i=0; i<a.size(); i++)
{
    if( !a[i].alive() )
    {

        a.erase(a.begin() + i);
        b.erase(b.begin() + i);
        i--;
    }
}

有没有一种方法可以更有效地执行此操作,并且最好使用stl算法?

Is there a way that I can do this more efficiently and preferably using stl algorithms?

如果顺序无关紧要,您可以将元素交换到向量的后面,然后将其弹出.

If order doesn't matter you could swap the elements to the back of the vector and pop them.

for(size_t i=0; i<a.size();)
{
    if( !a[i].alive() )
    {
        std::swap(a[i], a.back());
        a.pop_back();
        std::swap(b[i], b.back());
        b.pop_back();
    }
    else
      ++i;
}

如果您必须保持顺序,则可以使用 std :: remove_if .请参见此答案如何获取删除谓词中被取消引用的元素的索引:

If you have to maintain the order you could use std::remove_if. See this answer how to get the index of the dereferenced element in the remove predicate:

a.erase(remove_if(begin(a), end(a),
        [b&](const myClass& d) { return b[&d - &*begin(a)].alive(); }),
        end(a));

b.erase(remove_if(begin(b), end(b), 
        [](const otherClass& d) { return d.alive(); }), 
        end(b));