如何移除二维vector中的空元素?现有代码索引异常求修正
解决二维vector移除空元素时索引错误的问题
嘿,这个坑我之前踩过!你分析得完全正确——当调用erase后,vector的大小会立即缩减,后续的i++会跳过紧邻被删除元素的下一个元素,导致有些空vector没被删掉,所以最后输出了5而不是预期的2。下面给你三种实用的修正方案:
方法1:反向遍历删除
从vector的末尾开始往前遍历,这样即使删除了当前元素,前面的元素索引不会受到影响,不会出现跳过的情况:
#include<iostream> #include<vector> using namespace std; int main() { vector<vector<int>> vec(9); // 注意不要用vector当变量名,会和std::vector冲突! vec[0].push_back(2); vec[3].push_back(5); cout << vec.size() << endl; // 输出9 // 反向遍历 for (int i = vec.size() - 1; i >= 0; --i) { if (vec[i].empty()) { vec.erase(vec.begin() + i); } } cout << vec.size() << endl; // 输出2,符合预期 }
注意:我把变量名从vector改成了vec,避免和标准库的std::vector重名,这是个好习惯哦!
方法2:使用迭代器遍历(STL推荐方式)
用迭代器遍历的时候,erase会返回指向被删除元素下一个位置的有效迭代器,我们可以利用这个特性来更新迭代器,避免索引混乱:
#include<iostream> #include<vector> using namespace std; int main() { vector<vector<int>> vec(9); vec[0].push_back(2); vec[3].push_back(5); cout << vec.size() << endl; // 输出9 auto it = vec.begin(); while (it != vec.end()) { if (it->empty()) { it = vec.erase(it); // erase返回下一个有效迭代器,直接赋值给it } else { ++it; // 只有当前元素不用删除时,才移动迭代器 } } cout << vec.size() << endl; // 输出2 }
这种方式比索引遍历更符合STL的设计思想,也不容易出错。
方法3:erase-remove惯用法(最简洁高效)
这是STL中删除特定元素的标准范式,结合remove_if和erase,代码非常简洁,效率也很高:
#include<iostream> #include<vector> #include<algorithm> // 需要包含algorithm头文件 using namespace std; int main() { vector<vector<int>> vec(9); vec[0].push_back(2); vec[3].push_back(5); cout << vec.size() << endl; // 输出9 // remove_if把所有空vector移到末尾,返回第一个空vector的迭代器 auto new_end = remove_if(vec.begin(), vec.end(), [](const vector<int>& v) { return v.empty(); }); // erase删除从new_end到末尾的所有元素 vec.erase(new_end, vec.end()); cout << vec.size() << endl; // 输出2 }
remove_if会把不需要删除的元素移到容器前面,然后返回第一个要删除元素的迭代器,最后erase一次性删除所有要移除的元素,这种方式减少了多次erase带来的元素移动开销,适合大数据量的场景。
内容的提问来源于stack exchange,提问作者Xihao
相关产品推荐
相关产品推荐

