2024-01-12 10:40:20
在C++中,在循环中安全删除vector元素需避免迭代器失效或越界问题,以下是三种推荐方法及示例:
1. 使用反向迭代器从后往前删除原理:vector删除元素仅影响被删位置之后的元素,反向遍历可确保未遍历部分不受影响。步骤:
示例代码:
#include <vector>#include <iostream>int main() { std::vector<int> vec = {1, 2, 3, 4, 5, 2}; for (auto it = vec.rbegin(); it != vec.rend(); ) { if (*it == 2) { // 转换为正向迭代器并删除 vec.erase((it + 1).base()); it = vec.rbegin(); // 重置反向迭代器 } else { ++it; } } for (int num : vec) std::cout << num << " "; // 输出:1 3 4 5 return 0;}适用场景:需逐个判断元素且逻辑简单时。
2. 使用索引逆序遍历原理:通过整数索引从后往前遍历,避免迭代器转换和失效问题。步骤:
示例代码:
#include <vector>#include <iostream>int main() { std::vector<int> vec = {1, 2, 3, 4, 5, 2}; for (int i = vec.size() - 1; i >= 0; --i) { if (vec[i] == 2) { vec.erase(vec.begin() + i); } } for (int num : vec) std::cout << num << " "; // 输出:1 3 4 5 return 0;}适用场景:初学者或需明确索引控制的场景。
3. 采用remove-erase惯用法(推荐)原理:
示例代码:
#include <vector>#include <algorithm>#include <iostream>int main() { std::vector<int> vec = {1, 2, 3, 4, 5, 2}; // 删除所有值为2的元素 vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end()); for (int num : vec) std::cout << num << " "; // 输出:1 3 4 5 return 0;}复杂条件示例(使用std::remove_if):
#include <vector>#include <algorithm>#include <iostream>int main() { std::vector<int> vec = {1, 2, 3, 4, 5, 6}; // 删除所有偶数 vec.erase( std::remove_if(vec.begin(), vec.end(), [](int n) { return n % 2 == 0; }), vec.end() ); for (int num : vec) std::cout << num << " "; // 输出:1 3 5 return 0;}适用场景:批量删除或复杂条件判断时(优先推荐)。
关键注意事项remove-erase:仅移动元素一次,性能最优。
反向迭代器/索引遍历:需多次移动元素,适合小规模数据。