C++ STL矢量擦除

Czo*_*oka 2 c++ stl vector

问题是,当我运行该功能时,它在erase部件崩溃,我无法弄清楚原因.

void Grupa::del() {
    int size = studenti.size();
    for (int i=0; i<size; i++) {
        if (studenti[i].materia1<5 && studenti[i].materia2<5 && studenti[i].materia3<5) {
        studenti.erase(studenti.begin()+i);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*our 12

擦除元素时,向量变小; 但你仍然使用原始尺寸,并从最后掉下来.此外,您不希望i在擦除后增加,否则您将在删除后跳过该元素.所以你想要这样的东西:

for (size_t i = 0; 
     i != studenti.size(); // don't hoist out of the loop
     /* don't increment here */) 
{
    if (...) {
        studenti.erase(studenti.begin()+i);
    } else {
        ++i;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者看看"擦除 - 删除"这个习惯用法的其他答案,这是一种很好的,也许是更有效的方法,可以避免这种容易出错的逻辑.


Bil*_*eal 6

看起来你应该使用STL算法,std::remove_if而不是这个,这可以方便地避免其他回答者已经指出的问题.请考虑一下:

studenti.erase(std::remove_if(studenti.cbegin(), studenti.cend(), [](Student const& currentStudent) {
    return currentStudent.materia1<5 && currentStudent.materia2<5 && currentStudent.materia3<5;
}), studenti.cend());
Run Code Online (Sandbox Code Playgroud)

请注意,这优于您的解决方案,因为它相对于向量中的元素数量需要线性时间,而for/erase解决方案需要二次时间.