Effective STL学习笔记--慎重选择删除元素的方法

  • 要删除容器中有特定之的所有对象:
              container<int> c;

          如果容器是vector、string或deque,则使用erase-remove习惯用法
                    c.erase(remove(c.begin(), c.end(), 1999), c.end));//删除容器c(vector、string、deque)中所有值为1999的元素

          如果容器是list,则使用list::remove。
                    c.remove(1999);

          如果容器是一个标准关联容器,则使用它的erase成员函数。
                    c.erase(1999);

  • 要删除容器中满足特定判别式(条件)的所有对象:
              bool badValue(int);//返回x是否为“坏值”(要删除的值)

          如果容器是vector、string或deque,则使用erase-remove_if习惯用法。  
                    c.erase(remove_if(c.begin(), c.end(), badValue), c.end());

          如果容器是list,则使用list::remove_if。
                    c.remove_if(badValue);

          如果容器是一个标准关联容器,则使用remove_copy_if和swap,或者写一个循环来遍历容器中的元素,记住当把迭代器传给erase时,要对它进行后缀递增。
          方法1(易于编码,效率低)利用remove_copy_if把我们需要的值拷贝到一个新容器中,然后把原来容器的内容和新容器的内容相互交换。
                    AssocContainer<int> c;
                    AssocContainer<int> goodValues;//保存不被删除的值的临时容器
                    remove_copy_if(c.begin(), c.end(), inserter(goodValues, goodValues.end()), badValue);//把不被删除的值从c拷贝到goodValues中
                    c.swap(goodValues);//交换c和goodValues的内容
          方法2(效率高)写一个循环来遍历c中的元素,并在遍历过程中删除元素。
                    for(AssocContainer<int>::iterator i = c.begin(); i != c.end(); ++ i)
                    {
                         if(badValue(*i)) c.erase(i ++);//一旦erase(i)返回,i就成了无效值,++i也就失效
                         else ++i;
                    }

  • 要在循环内部做某些(除了删除对象之外的)操作:
              ofstream logFile;//要写入的日志文件
              AssocContainer<int> c;
    如果容器是一个标准序列容器,则写一个循环来遍历容器中的元素,记住每次调用erase是,要用它的返回值更新迭代器。
               for(SeqContainer<int>::iterator i = c.begin(); i != c.end(); ) //vector、string和deque
              {
                   if(badValue(*i))
                   {
                        logFile << "Erasing " << *i << '\n';//写入日志文件
                        i = c.erase(i);//把erase的返回值赋给i,使i的值保持有效
                   }
                   else ++i;
              }

          如果容器是一个标准关联容器,则写一个循环来遍历容器中的元素,记住当把迭代器传给erase时,要对迭代器做后缀递增。
                    for(AssocContainer<int>::iterator i = c.begin(); i != c.end(); )
                    {
                         if(badValue(*i))
                         {
                              logFile << "Erasing " << *i << '\n';//写入日志文件
                              c.erase(i ++);//删除元素
                         }
                         else ++i;
                    }

posted on 2009-02-17 09:55  人间爱  阅读(484)  评论(0)    收藏  举报

导航