Clause 19 删除元素的方法

Clause 19 删除元素的方法
1、对于连续内存的容器(vector,dequeu,string),最好的方法是用erase - remove
     c.erase(remove(c.begin(),c.end(),1963),c.end());
    /* remove(first,end,value)  : The remove algorithm removes all elements that match value from the range (First, Last). It returns an iterator equal to Last - n, where n = number of elements removed. That is ,if c is {3,2,1963,12,1963,16}, after remove , c is {3,2,12,16,1963,1963}.*/
2、对于list,c.remove(1963);
3、对于关联容器(map,set) 可以用c.erase(1963);  而且开销是对数时间的。而前两条中的开销是线性的。 
3、如果是要删除满足某一条件的值,对于连续内存的容器(vector,dequeu,string),用erase - remove_if。对于list,用remove_if
c.erase(remove_if(c.begin(),c.end(),yourcondition),c.end());  /*删除使youcondition为true的值*/
4、对于关联容器,必须遍历整个容器中的元素了。
     下面是重点:
      下面的程序是不对的
     

AssocContainer
< int > c;

for (AssoContainer < int > ::iterator i = c.begin();i != c.end();i ++ )
    
if (youcondition( * i)) c.erase(i);
 
因为当把i删除后,i就变成了无效的值。这样,后面的i++就无效了。

解决这个问题的最简单的方法是:


5、第4条所述的方法,只对关联容器起作用。对于vector,string,dequeu,上面的方法会出错。因为这类容器,当删除一个元素后,不仅指向被删除的元素的迭代器无效,也会使被删除元素之后的所有的迭代器失效。
这时,我们要用erase的返回值。erase返回被删除元素的下一个元素的有效的迭代器。
因此可以这样
SeqContainer < int > c;

for (SeqContainer < int > ::iterator i = c.begin();i != c.end();)
{
    
if (youcondition( * i)) 
    {
        dosomething(
* it);
        i
= c.erase(i);
    }
    
else  i ++ ;
}

    还要注意,对于关联容器,erase返回void.



总结:

● 去除一个容器中有特定值的所有对象:

如果容器是vector、string或deque,使用erase-remove惯用法。

如果容器是list,使用list::remove。

如果容器是标准关联容器,使用它的erase成员函数。

● 去除一个容器中满足一个特定判定式的所有对象:

如果容器是vector、string或deque,使用erase-remove_if惯用法。

如果容器是list,使用list::remove_if。

如果容器是标准关联容器,使用remove_copy_if和swap,或写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。

● 在循环内做某些事情(除了删除对象之外):

如果容器是标准序列容器,写一个循环来遍历容器元素,每当调用erase时记得都用它的返回值更新你的迭代器。

如果容器是标准关联容器,写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。

你可能感兴趣的:(Clause 19 删除元素的方法)