32、如何解决vector中删除元素导致的迭代器失效问题?
使用 标准库提供的算法,如 std::remove
或 std::remove_if
结合 vector::erase
方法来删除元素。这些算法在设计时已经考虑了迭代器失效的问题:
std::remove
结合vector::erase
方法
//remove(beg,end,const T& value) ,移除区间[beg,end)中每一个“与value相等”的元素,所以需要传入一个值
//remove()并不会实际移除序列[start, end)中的元素,
//只是将符合条件的元素移动到容器末尾 并 返回(指向第一个要移除的元素的位置的)迭代器,
//因此可以同时配合erase对vector容器中的元素进行清除
#include <iostream>
#include <vector>
#include <algorithm> // [注意] :remove位于algorithm函数库中
int main()
{
std::vector<int> vecInt{0, 1 , 2 ,3 ,4};
std::cout << vecInt.size() << std::endl; // 输出的结果为5,容器中存了5个元素
std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量
vecInt.erase(std::remove(vecInt.begin(), vecInt.end(), 3), vecInt.end());
std::cout << vecInt.size() << std::endl; // 输出的结果为4,容器中存了4个元素
std::cout << vecInt.capacity() << std::endl; // 输出的结果为5,容器在内存开辟空间的容量
for(auto i : vecInt)
{
std::cout << i << std::endl;
}
}
// 使用remove之前,容器vector的值为: 0,1,2,3,4
// 使用remove函数删除值为3的元素后,容器vector的值为:0,1,2,4,4
// 再配合erase后,容器vector的值为:0,1,2,4
// 可以看出remove,容器的size变成了size-1,删除了值为3的元素。容器的capacity不变
std::remove_if
结合vector::erase
方法
//remove_if(beg, end, op) ,移除区间[beg,end)中每一个“令判断式:op(elem)获得true”的元素,所以需要传入一个函数指针
//remove_if()并不会实际移除序列[start, end)中的元素,
//只是将符合条件的元素移动到容器末尾 并 返回(指向第一个要移除的元素的位置的)迭代器,
//因此可以同时配合erase对vector容器中的元素进行清除
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
bool isSpace(char x) { return x == ' '; }
int main()
{
string s2("Text with spaces");
cout << "删除之前"<<s2 << endl;
s2.erase(remove_if(s2.begin(), s2.end(), isSpace), s2.end());
cout <<"删除之后"<< s2 << endl;
return 0;
}
/*
程序输出为:
删除之前Text with spaces
删除之后Textwithspaces
*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<string> str = { "apple", "banana", "key", "cat", "dog", "orange", "banana" };
auto find_str = "banana";
auto sd = remove_if(str.begin(), str.end(), [find_str](string n) { return n == find_str; });
str.erase(sd, str.end());
str.erase(remove_if(str.begin(), str.end(),
[find_str](string n) { return n == find_str; }),
str.end());
vector<string>::iterator iter;
for (iter = str.begin(); iter != str.end(); ++iter)
{
cout << "删除之后:"<<*iter<<" ";
}
return 0;
}
//apple key cat dog orange