首先我们看一下如何使用earse函数删除容器中的元素,尤其要注意容器中某个值有多个的情况。
一,使用 remove 算法和容器的 erase 函数
remove 算法不是真正从容器中删除元素,而是将需要删除的元素移到容器末尾,返回指向新的逻辑末尾的迭代器。需结合容器的 erase 函数真正删除元素。示例如下:
std::vector<int> vec = { 1, 2, 5, 2, 8, 2, 6 };
// 使用remove算法和erase函数删除值为2的元素
auto newEnd = std::remove(vec.begin(), vec.end(), 2);
vec.erase(newEnd, vec.end());
// 输出剩余元素
for (int i : vec)
{
std::cout << i << " ";
}
输出结果如下:
1 5 8 6
二,使用 erase和remove_if
用于删除满足特定条件的元素。 remove_if 算法会将满足条件的元素移到容器末尾,返回新的逻辑末尾迭代器,再通过 erase 函数删除。
std::vector<int> vec = { 1, 2, 5, 2, 8, 2, 6 };
// 使用erase-remove_if惯用法删除值为2的元素
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x) { return x == 2; }), vec.end());
// 输出剩余元素
for (int i : vec)
{
std::cout << i << " ";
}
输出结果如下:
1 5 8 6
三,使用关联容器的 erase 成员函数结合查找算法
- 对于关联容器如 std::set 、 std::map 可以使用 find 函数找到要删除的元素,再调用 erase 函数删除。
std::set<int> setData = { 1, 2, 3, 4, 5 };
// 查找并删除值为2的元素
auto it = setData.find(2);
if (it != setData.end()) {
setData.erase(it);
}
// 输出剩余元素
for (int i : setData)
{
std::cout << i << " ";
}
四,通过循环的方法删除
这种方法就是本文重点要讲到的方法。
std::vector<int> vec = { 1, 2, 5, 2, 8, 2, 6 };
//利用循环方式删除
std::vector<int>::iterator it = vec.begin();
for (; it != vec.end(); it++)
{
if (*it == 2)
{
vec.erase(it);
}
}
// 输出剩余元素
for (int i : vec)
{
std::cout << i << " ";
}
如果采用上面的方式在循环中直接删除元素,会导致程序的崩溃。
究其原因是在使用 erase 函数删除元素时,会导致后面的迭代器失效。解决方法也很简单就是要及时更新迭代器。方法如下:
std::vector<int> vec = { 1, 2, 5, 2, 8, 2, 6 };
auto it = vec.begin();
while (it != vec.end())
{
if (*it == 2)
{
it = vec.erase(it); // 更新迭代器
}
else
{
++it;
}
}
// 输出剩余元素
for (int i : vec)
{
std::cout << i << " ";
}