簡體   English   中英

C ++ STL矢量擦除

[英]C++ STL vector erase

問題是,當我運行該功能時,它會在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);
        }
    }
}

擦除元素時,向量變小; 但你仍然使用原始尺寸,並從最后掉下來。 此外,您不希望在擦除后增加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;
    }
}

或者看看“erase-remove”習語的其他答案,這是一種很好的,也許是更有效的方法,可以避免這種容易出錯的邏輯。

看起來你應該使用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());

請注意,這優於您的解決方案,因為它相對於向量中的元素數量需要線性時間,而for / erase解決方案需要二次時間。

i超越了矢量的大小。 由於erase調用,向量的大小變小,但是直到保存的大小,如果有已擦除的項目,則大於實際大小。

這就是erase返回迭代器的原因,它是擦除的元素旁邊元素的有效迭代器:

for (auto it = studenti.begin(); it != studenti.end();) {
    if (it->materia1<5 && it->materia2<5 && it->materia3<5)
        it = studenti.erase(it);
    else
        ++it;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM