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);
}
}
}
当你擦除一个元素时,vector会变小;但你还是用原来的尺寸,并且从末端脱落。此外,您不希望在擦除后增加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;
}
相关文章:
- C++ STL 设置按值擦除
- 擦除是否删除 stl 无序列图元素使用的堆内存
- 在 stl 中的字符串中擦除关键字的工作?
- 迭代时从 STL 容器中查找并擦除元素
- 如何在下一次函数调用中使用 STL 映射擦除从最后一个位置
- STL矢量通过指针擦除
- 如何不擦除迭代器(从"Effective STL")
- 有没有一种方法可以防止在STL无序映射上插入或擦除
- 在C++STL映射上通过迭代器擦除
- STL 矢量擦除不起作用
- STL 关联容器:擦除并取回(不可复制的)元素
- STL 映射不会擦除
- STL 允许使用指向不同映射的迭代器擦除映射的键/值?
- 如何使用STL算法和函数按值擦除std::映射单元格
- 调整STL矢量的大小是否会擦除/使其以前的内容无效
- STL矢量擦除后的迭代器无效
- 用常量迭代器从STL容器中擦除
- c++ STL矢量擦除
- 按键擦除STL std::set元素时发生编译错误
- C++ STL 字符串擦除