关于erase,我的理解就是:删除指定的元素,然后把刚刚删除的元素其后面所有元素往前移.然后改变end指针.使其往前移动一位.最重要的是,当前的迭代器不动(但是由于元素往前移了,所以它指向了原始状态的下一个元素).
比如我有一个vector,vector的元素分别是0,1,2,3,4;如果我想删除元素值为3的元素.那么当我使用erase后,它的内存元素分别为0(begin),1,2,4(end),4.删除以后的迭代器指向的元素为4.(是第一个4)
看起来比较啰嗦,按照这一原理我们来看几个简单的例子.
首先是初学者最容易忽视的一个问题:
vector<int> vectInt;
int i;
for (i = 0; i < 5; i++ )
{
vectInt.push_back( i );
}
// 以下代码是要删除所有值为 4 的元素
vector<int>::iterator itVect = vectInt.begin();
for ( ; itVect != vectInt.end(); ++itVect )
{
if ( *itVect == 4 )
{
vectInt.erase( itVect );
}
}
这段代码是一般初学者写的.这里主要是牵涉到迭代器失效的问题.(这里只是简单的描述一下错误)实际上问题比较大,我暂时不讨论.
我们先来看另外一个例子:
vector<int> vectInt;
int i;
// 初始化 vector 容器
for ( i = 0; i < 5; i++ )
{
vectInt.push_back( i );
if ( 3 == i )
{
vectInt.push_back( i );
}
}
vector<int>::iterator itVect = vectInt.begin();
vector<int>::iterator itVectEnd = vectInt.end();
// 以下代码是要删除所有值为 3 的元素
for ( ; itVect != itVectEnd; ++itVect )
{
if ( *itVect == 3 )
{
itVect = vectInt.erase( itVect );
}
}
//这里是输出元素
int iSize = vectInt.size();
for ( i = 0 ; i < iSize; i++ )
{
cout << " i= " << i << ", " << vectInt[ i ] << endl;
}
getchar();
这里我们可以简单的调试一下程序.就会发现当我删除了一个元素值为3以后,整个后面的向量向前移动了一个单位.所以就会漏删一个元素.
输出结果为:
我把输出的那段换成一下代码就可以发现其实现的原理:
int iSize = vectInt.size();
for ( i = 0 ; i < iSize + 2; i++ )
{
cout << " i= " << i << ", " << vectInt[ i ] << endl;
}
getchar();
发现其输出结果为:
最后还有一个问题:
为什么我把指定的数删除以后,整个向量的大小并没有改变?
也就是说.我以前有0~5个元素,当我删除掉一个元素以后,元素的前移为什么没有注销掉最后一个内存块?
按照我的理解,因为当你生成一个vector对象以后,并不是你pushback一次他就申请一次,而是先初始化一段内存块.待你需要存储的区域比当时初始化的大小要大时,它才会有申请一个增量空间,供你再次使用.所以,我觉得系统没有必要把后面移动后的元素的内存清空(因为它本来就占用了内存了的),它只是简单的把end指针移动一下.这样,等你下一次来增加元素的时候,它覆盖就行了.
还有一点是,要注意vector的存储方式:顺序存储.
仔细体会上述两个简单的例子,就不难写出删除某一特定组元素的代码:
void deleteItem( vector<int>& vecInt,int deleteValue )
{
for ( vector<string>::iterator iter = vecInt.begin();iter != vecInt.end(); )//这里需要注意的一个小问题是,end指针不能保存使用
{
if ( *iter == deleteValue )
{
iter = vecInt.erase( iter );
continue;
}
iter ++;
}
return;
}