1. remove算法和容器的erase成员函数
remove
操作移除[first,last)之中所有与value相等的元素。这一算法并不真正从容器中删除那些元素(换句话说容器的大小并没有改变),而是将每一个不与value相等的元素轮番赋值给first之后的空间。也就是说,所有和value相同值的元素都会被覆盖,而其他的元素都会依次前移。最后remove返回"指向最后一个 '有用' 元素的iterator",但是在remove算法过程中,并没有修改原容器的size,以及end()。
移除容器里面的元素不应该使用remove算法,而是容器自己的方法erase()。
为什么这么设计:
STL将算法和数据结构分离开来,以迭代器为接口,迭代器对自己所属的容器一无所知。任何“以迭代器访问容器元素”的算法,都不得(无法)透过迭代器调用容器类别所提供的任何成员函数。
删除元素可以使用如下语句:c.erase(remove(beg, end), c.end() );将逻辑终点和物理终点之间的元素删除。
特殊情况:
①
List:
由于List不是顺序容器,调用remove算法会使移动被删除元素之后的元素,效率很低,所以使用自身的remove成员函数,直接更改指针的指向即可。
②Set等关联容器:
从迭代器的角度来看,容器中的元素都是常量,这保证不能人为改变元素的值,从而打乱元素的顺序,所以不能对Set元素调用变动性算法。
因为remove算法是用后面的元素覆盖被删除元素,所以不能调用remove算法,只能使用set容器的成员函数erase()
2. 顺序容器和关联容器的find与erase
①关联容器查找元素时应使用成员函数find(),而不是通用算法find(),因为关联容器底层是二叉树,使用成员函数find可以获得更好的性能。
②关联容器中的erase成员函数,与顺序容器中的erase成员函数返回值不同,顺序容器erase返回被删除元素的下一个元素的iterator,而关联容器不返回任何东西。同样也是因为关联容器底层是二叉树,返回后继节点可能颇为耗时。
注意:使用erase时,该迭代器会失效,故在循环中使用erase时:
①对顺序容器和list:使用erase的返回值来更新迭代器
②对关联容器:erase(pos ++),先对pos加1获得下一个元素的迭代器,然后再删除当前元素。