为生存而奔跑

   :: 首页 :: 联系 :: 聚合  :: 管理
  271 Posts :: 0 Stories :: 58 Comments :: 0 Trackbacks

留言簿(5)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 324043
  • 排名 - 74

最新评论

阅读排行榜

评论排行榜

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时记得后置递增它。

posted on 2009-10-24 21:13 baby-fly 阅读(190) 评论(0)  编辑 收藏 引用 所属分类: Effective STL / C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理