您的位置:首页 > 其它

STL remove和erase

2015-12-02 14:44 232 查看
remove 算法描述:查找的得到第一个元素的位置,然后从此位置开始遍历容器,将后面的元素依次前移,跳过和value相同值的元素,也就是说,所有和value相同值的元素都会被覆盖,而其他的元素都会依次前移。最后remove返回"指向最后一个 '有用' 元素的iterator",但是在remove算法过程中,并没有修改原容器的size,以及end()。但是从逻辑角度看,最后的[
从remove得到的iterator---_result, 容器的结尾end() ) 这个区间里面的元素已经没有意义了。所以这些元素不应该属于该容器了。remove算法能做的仅此而已,并没有删除这些无用的元素。

结论:移除容器里面的元素不应该使用remove算法,而是容器自己的方法erase()。

erase使用:

#include <iostream>

#include <vector>

using namespace std;

int main()

{

vector<int> arr;

arr.push_back(6);

arr.push_back(7);

arr.push_back(8);

arr.push_back(9);

for(vector<int>::iterator it=arr.begin(); it!=arr.end(); )

{

if(* it == 8)

{

it = arr.erase(it);

}

else

{

++it;

}

}

//注意上面不能写成

/*

for(vector<int>::iterator it=arr.begin(); it!=arr.end(); it ++)

{

if(* it == 8)

{

arr.erase(it); //在erase后,it失效,并不是指向vector的下一个元素,it成了一个“野指针”。

}

}

*/

}

*******************************************************************************************


条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase

只有容器成员函数可以除去容器元素:如果你真的要删除东西的话,你应该在remove后面接上erase。

你要erase的元素很容易识别。它们是从区间的“新逻辑终点”开始持续到区间真的终点的原来区间的元素。要除去那些元素,你要做的所有事情就是用那两个迭代器调用erase的区间形式(参见条款5)。因为remove本身很方便地返回了区间新逻辑终点的迭代器,这个调用很直截了当:
vector<int> v;						// 正如从前
v.erase(remove(v.begin(), v.end(), 99), v.end());		// 真的删除所有
// 等于99的元素
cout << v.size();						// 现在返回7


把remove的返回值作为erase区间形式第一个实参传递很常见,这是个惯用法。事实上,remove和erase是亲密联盟,这两个整合到list成员函数remove中。这是STL中唯一名叫remove又能从容器中除去元素的函数:
list<int> li;			// 建立一个list
// 放一些值进去
li.remove(99);			// 除去所有等于99的元素:
// 真的删除元素,
// 所以它的大小可能改变了


坦白地说,调用这个remove函数是一个STL中的矛盾。在关联容器中类似的函数叫erase,list的remove也可以叫做erase。但它没有,所以我们都必须习惯它。我们所处于的世界不是所有可能中最好的世界,但却是我们所处的。(附加一点,条款44指出,对于list,调用remove成员函数比应用erase-remove惯用法更高效。)

一旦你知道了remove不能“真的”从一个容器中删除东西,和erase联合使用就变成理所当然了。你要记住的唯一其他的东西是remove不是唯一这种情况的算法。另外有两种“类似remove”的算法:remove_if和unique。

remove和remove_if之间的相似性很直截了当。所以我不会细讲,但unique行为也像remove。它用来从一个区间删除东西(邻近的重复值)而不用访问持有区间元素的容器。结果,如果你真的要从容器中删除元素,你也必须成对调用unique和erase,unique在list中也类似于remove。正像list::remove真的删除东西(而且比erase-remove惯用法高效得多)。list::unique也真的删除邻近的重复值(也比erase-unique高效)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: