STL序列式容器中删除元素的方法和陷阱二

转载 2006年06月15日 13:24:00

2.使用 STL 中通用算法或容器成员函数删除元素的方法

以上手工编写 for 循环代码删除容器中元素的方法也有一些问题,如果判断条件特别复杂,又有循环判断的话,循环中间又有异常处理的话, ++itVect 的位置就要小心放置了,稍不留意就要出错。所以手工编写代码删除容器中元素的方法不太安全,代码重复,也不够优雅,要注意的地方很多。

对于这种情况,可以考虑使用 STL 中通用算法 remvoe() remove_if() 帮忙。而 remvoe() remove_if() 这两个算法也有一个问题需要程序员特别小心。 在通用算法中的 remove (包括 remove_if 函数,并不真正从容器中删除元素,而是“应被删除的元素”被其后的“未被删除的元素”覆盖。返回值 ForwardIterator 指向经移除后的最后元素的下一位置。如 vector{0,1,2,3,3,4} ,执行 remove() ,希望移除所有值为 3 的元素,结果为 {0,1,2,4,3,4} ,返回值 ForwardIterator 指向第 5 个元素。即:

0        1        2        3         3       4  移除前

0        1        2        4         3       4  移除后

 

移除值为 3 的元素。移除后 3 被其后的 4 替代,最后两位元素为残余数据。

 

5

void main() {

       vector<int> vectInt;

       int i;

       for (i = 0; i < 5; i++ ) {

              vectInt.push_back( i );

              if ( 3 == i ) {

                     vectInt.push_back( i );

              }

       }

       remove( vectInt.begin(), vectInt.end(), 3 );

       cout << " after deleted , size = " << vectInt.size() << endl;

       for ( i = 0; i < vectInt.size();; i++ ) {

              cout << "i = " << i << " , " << vectInt[i] << endl;

       }

}

运行结果为:

after deleted , size = 6 // 从这行可以看出,移除后容器的大小没变

i = 0 , 0

i = 1 , 1

i = 2 , 2

i = 3 , 4 //  从这行可以看出:“应被删除的元素” 3 被其后的“未被删除的元素” 4 覆盖

i = 4 , 3

i = 5 , 4     

 

所以要彻底删除还应该把后面的残余数据删除掉,这可以通过调用容器的成员函数 erase() 做到。

6

void main() {

       vector<int> vectInt;

       int i;

       for (i = 0; i < 5; i++ ) {

              vectInt.push_back( i );

              if ( 3 == i ) {

                     vectInt.push_back( i );

              }

       }

       vectInt.erase( remove( vectInt.begin(), vectInt.end(), 3 ), vectInt.end() );

       cout << " after deleted , size = " << vectInt.size() << endl;

       for ( i = 0; i < vectInt.size();; i++ ) {

              cout << "i = " << i << " , " << vectInt[i] << endl;

       }

}

运行结果为:

after deleted , size = 4 // 从这行可以看出,删除后容器的大小变化了

i = 0 , 0

i = 1 , 1

i = 2 , 2

i = 3 , 4

从结果可以看出,所有值为 3 的元素确实被删除了。

对于 vector 容器存放其他比较复杂的对象,就可以用 remove_if() 加函数对象( Function Object )的方法。

如:

7

#include <iostream>

#include <sstream>

#include <string>

#include <vector>

#include <algorithm>

#include <list>

using namespace std;

class CTest {

public:

       CTest( const string& str, int iPrice ) : m_strName( str ), m_iPrice( iPrice ) { }

      void vPrint() { cout << "name=" << m_strName << " price = " << m_iPrice << endl;

       }

private:

       string m_strName;

       int   m_iPrice;

       //     由于两个函数对象要访问 CTest 类的 private 成员,所以设为友员。

       friend class CStrFunc;

       friend class CIntFunc;

};

//     函数对象,根据 string 比较

class CStrFunc {

       string m_str;

public:

       CStrFunc( const string& str ) : m_str( str ) {

       }

       bool operator() ( const CTest& left ) {

              return ( m_str == left.m_strName ) ? true : false;

       }

};

//     函数对象,根据 int 比较

class CIntFunc {

       int m_iPrice;

public:

       CIntFunc( int iPrice ) : m_iPrice( iPrice ) {

       }

       bool operator() ( const CTest& left ) {

              return ( m_iPrice == left.m_iPrice ) ? true : false;

       }

};

void main( ) {

 

       vector< CTest > vectTest;

       int i;

       for (  i = 0; i < 5 ; i++ ) {

              stringstream stream; //       流格式化符,把 int 转化为 string

              stream << i;

              string str = stream.str();

              CTest clTest( str, i );

              vectTest.push_back( clTest );

       }

      for (  i = 0 ; i < vectTest.size(); i++ )  {

              vectTest[ i ].vPrint();

       }

       //     删除所有 m_strName = "3" 的元素

       vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CStrFunc( "3" ) ),

              vectTest.end() );

       cout << "delete 3 after : " << endl;

      for (  i = 0 ; i < vectTest.size(); i++ )  {

              vectTest[ i ].vPrint();

       }

       //     删除所有

STL序列式指针容器中删除元素的方法

在STL(标准模板库)中经常会碰到要删除容器中部分元素的情况,本人在编程中就经常编写这方面的代码,在编码和测试过程中发现在STL中删除容器有很多陷阱,网上也有不少网友提到如何在STL中安全删除元素这些...

STL:循环删除容器中元素的方法和陷阱

算法大师Donald Knuth:不成熟的优化是一切恶果的根源(Permature optimization is the root of all evil )。   STL中的容器主要是两种:序...

STL容器删除元素的陷阱

今天看Scott Meyers大师的stl的用法,看到了我前段时间犯的一个错误,发现我写的代码和他提到错误代码几乎一模一样,有关stl容器删除元素的问题,错误的代码如下: std::vector m...

循环删除容器中元素的方法和陷阱

算法大师Donald Knuth:不成熟的优化是一切恶果的根源(Permature optimization is the root of all evil )。 STL中的容器主要是两种:序列式容...

C++ STL容器遍历删除元素的方法

C++ STL容器遍历删除元素的方法  上周在做内存池回收的时候,遍历deque(使用了双端队列来管理内存块)的每一个元素,查找满足条件的内存块并进行回收,结果竟然coredump了。   写了个简...

总结STL中容器中元素的删除方法

首先看下面的关于删除容器中元素的例子(VS2010中编写):  #include "stdafx.h" #include #include #include #include #include...
  • BBOOT
  • BBOOT
  • 2015年03月22日 15:22
  • 765

c++中在顺序容器中访问、插入、删除元素的操作

c++中的顺序容器有vector,deque,queue,list,stack,priority_queue等 访问顺序容器内元素的操作: c.back( ) 返回容器c的最后一个元素的引用。...

Effective STL-各种容器正确删除元素方法

一、去除一个容器中有特定值得所有对象1、如果容器是vector、string或deque,使用erase-remove惯用法c.erase(remove(c.begin,c.end(),value),...

stl容器中的元素删除方法

STL中元素的删除方法: 问题描述: 对于容器:container c; 要删除其中元素值为1的元素。container为一类容器。 1、  连续内存的容器(vector、deque或stri...

【学习笔记】《STL使用入门教程》第六讲:容器使用时机、算法、删除元素的注意点

1、容器的共通能力 2、各个容器的使用时机 3、常用算法(Algorithm)的用法介绍...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章: STL序列式容器中删除元素的方法和陷阱二
举报原因:
原因补充:

(最多只允许输入30个字)