目录
- erase:
- remove:
vector中,
remove函数和
erase函数都可以实现元素的删除,但它们的用法稍微有些区别:
- erase是删除指定位置的元素或者指定区域内的所有元素
- remove是删除和指定元素值相同的所有元素(remove需要和erase搭配使用才能实现完整的删除功能)
erase:
iterator erase (const_iterator position); //删除指定位置的元素
iterator erase (const_iterator first, const_iterator last); //删除一段区域内的元素(last迭代器指向的元素不会被删除)
先来看一个例子
vector<int> vec = { 1,2,3,4,5,6,7 };
vector<int>::iterator itr = vec.begin();
while (itr != vec.end())
{
if (*itr == 1)
{
vec.erase(itr); //第一处错误,itr失效,称为野指针
}
itr++; //第二处错误,如果itr = erase返回值,这里itr就会自加两次
}
注意: 上述例子编译不会通过,因为被删除的迭代器会失效,变成一个野指针,这时再和末尾位置迭代器进行比较会出错,此时正确的做法是将erase的返回值赋值给itr,因为erase会返回被删除元素的下一个元素的迭代器。如果这样改了之后,itr ++ 也需要进行修改,避免自加两次。
vector<int> vec = { 1,2,3,4,5,6,7 };
vector<int>::iterator itr = vec.begin();
while (itr != vec.end())
{
if (*itr == 1)
{
itr = vec.erase(itr);
}
else
itr++;
}
remove:
template<class _FwdIt,
class _Ty>
_NODISCARD inline _FwdIt remove(_FwdIt _First, const _FwdIt _Last, const _Ty& _Val);
remove由定义在 algorithm 头文件中的模板生成,所以要用它需要加上 < algorithm >。
remove函数本质上其实并没有完成元素的完全删除工作,因为容器的大小都没有改变,它只是将所有被删除的元素用下一个不被删除的元素进行覆盖,同时返回一个迭代器,在该迭代器之前的所有元素,保留原容器的顺序,并且不存在被删除的元素,也就是你想要的容器内容,而该迭代器到容器的末尾则不变,也就是说,原容器的大小没有发生变化,被删除的元素也确实没有了,但容器末尾的一些元素(个数等于被删除元素个数)又会多出来一份,这是我们不愿意看到的,因此需要借助上面提到的erase函数。所以说remove需要和erase搭配使用才能实现完整的删除功能。
vector<int> vec = { 1,1,3,4,5,6,7 };
vec.erase(remove(vec.begin(), vec.end(), 1), vec.end());