STL中慎重选择删除元素的方法



一、要删除容器中有特定值的所有对象

1、如果容器是vector、string或deque,则使用erase-remove习惯用法。例如:

vector<int> c;

c.erase(remove(c.begin(),c.end(),1963),c.end());//删除值是1963的元素

下面讲一下算法remove:

template<classForwardIterator,class T>

ForwardIteratorremove(ForwardIterator first,ForwardIterator last,const T& value)

{

first = find(first,last,value);

ForwardIterator next = first;

return first ==last?first:remove_copy(++next,last,first,value);

}

template<classInputIterator,class OutputIterator,class T>

OutputIteratorremove_copy(InputIterator first,InputIterator last,OutputIterator result,constT& value)

{

for(;first != last;++first)

if (*first != value)

{

*result = *first;

++result;

}

return result;

}

移除[first,last)之中所有与value相等的元素。这一算法并不真正从容器中删除那些元素(换句话说容器大小并为改变),而是将每一个不与value相等(也就是我们并不打算移除)的元素轮番赋值给first之后的空间。返回值标示出重新整理后的最后元素的下一位置。例如序列{0,1,0,2,0,3,0,4},如果我们执行remove(),希望移除所有0值元素,执行结果将是{1,2,3,4,0,3,0,4}。每一个与0不相等的元素,1,2,3,4,分别被拷贝到第一、二、三、四个位置上。第四个位置以后不动,换句话说是第四个位置之后是这一算法留下的残余数据。返回值ForwardIterator指向第五个位置。如果要删除那些残余数据,可将返回的迭代器交给区间所在之容器的erase()成员函数。注意,array不适合使用remove()和remove_if(),因为array无法缩小尺寸,导致残余数据永远存在。对array而言,较受欢迎的算法是remove_copy()和remove_copy_if()。

remove_copy移除[first,last)区间内所有与value相等的元素。它并不真正从容器中删除那些元素,而是将结果复制到一个以result标示起始位置的容器身上。新容器可以和原容器重叠,但如果对新容器实际给值时,超越了旧容器的大小,会产生无法预期的结果。返回值OutputIterator指出被复制的最后元素的下一位置。

2、如果容器是list,则使用list::remove。例如:

list<int> c;

c.remove(1963);//该成员函数无返回值

3、如果容器是一个标准关联容器,则使用它的erase成员函数。例如:

map<int,int>c;

c.erase(1963);//删除键值是1963的元素

对于标准关联容器使用任何名为remove的操作都是完全错误的。这样的容器没有名为remove的成员函数,使用remove算法可能会覆盖容器的值,同时可能会破坏容器。

二、要删除容器中满足特定判别式(条件)的所有对象

1、如果容器是vector、string或deque,则使用erase-remove_if习惯用法。例如我们不再从c中删除所有等于特定值的元素,而是删除使下面的判别式返回true的每一个对象:

bool badvalue(int);

c.erase(remove_if(c.begin(),c.end(),badvalue),c.end());

2、对于list,则使用list::remove_if。例如:

c.remove_if(badvalue);

3、如果容器是一个标准关联容器,则使用remove_copy_if和swap,或者写一个循环来遍历容器中的元素,记住当把迭代器传给erase时,要对它进行后缀递增。例如:

AssocContainer<int>c;

AssocContainer<int>goodvalues;

Remove_copy_if(c.begin(),c.end(),inserter(goodvalues,goodvalues.end()),badvalue);

c.swap(goodvalues);

或者

AssocContainer<int>c;

for(AssocContainer<int>::iteratori = c.begin();i != c.end();)

{

if(badvalue(*i))

c.erase(i++);

else

++i;

}

三、要在循环内部做某些(除了删除对象之外的)操作:

1、如果容器是一个标准序列容器,则写一个循环来遍历容器中的元素,记住每次调用erase时,要用它的返回值更新迭代器。例如:

ofstream logFile;

SeqContainer<int>c;

for (SeqContainer<int>::iteratori = c.begin();i != c.end();)

{

if (badvalue(*i))

{

logFile << “Erasing” << *i<< ‘\n’;

i = c.erase(i);//把erase的返回值赋给i,使i的值保持有效

}

else

{

++i;

}

}

2、如果容器是一个标准关联容器,则写一个循环来遍历容器中的元素,记住当把迭代器传给erase时,要对迭代器做后缀递增。例如:

ofstream logFile;

AssocContainer<int>c;

for(AssocContainer<int>::iterator i = c.begin();i != c.end();)

{

if (badvalue(*i))

{

logFile<< “Erasing ” << *i << ‘\n’;

c.erase(i++);

}

else

++i;

}

STL中慎重选择删除元素的方法,布布扣,bubuko.com

时间: 2024-10-01 05:52:44

STL中慎重选择删除元素的方法的相关文章

条目九《慎重选择删除元素的方法》

慎重选择删除元素的方法 不同容器删除元素的方法是有区别的. 对于删除容器里的一个元素 序列容器( string, vector, deque)最高效的方法是erase-remove. list最高效的方法是remove. 关联容器没有remove成员函数,只有erase,直接用erase函数来删除元素. 若删除容器里符合一个判别式的元素: 序列容器( string, vector, deque)最高效的方法是erase-remove_if. list最高效的方法是remove_if. 关联容器的

慎重选择删除元素的方法

总结本条款,一共有以下几点是需要牢记的: 1.要删除容器中有特定值的所有对象: (1).如果容器是vector.string或deque,则使用erase-remove习惯用法. (2).如果容器是list,则使用list::remove (3).如果容器是标准关联容器,则使用它的erase成员函数. eg:  假定你有一个标注的STL容器c,它包含int类型的整数:Container<int> c; 而你想删除c中所有值为1963的元素.则可以使用erase-remove.习惯用法: c.e

慎重选择删除元素的方法STL

1.要删除容器中有特定之的所有对象: 如果容器是vector.string或deque,则使用erase-remove习惯用法. 如果容器是list,则使用list::remove. 如果容器是一个标准关联容器,则使用它的erase成员函数. 2.要删除容器中满足特定判别式(条件)的所有对象: 如果容器是vector.string或deque,则使用erase-remove_if习惯用法. 如果容器是list,则使用list::remove_if. 如果容器是一个标准关联容器,则使用remove

STL 中 使用迭代器删除元素的问题

在vector中删除,大家都知道,直接erase的话,这种写法很有问题.因为erase(iter)之后iter指针就变成野指针了,此时继续iter++就会出问题. 1 for(auto iter = v.begin(), iter!=v.end(); iter++) 2 { 3 if(iter == 3) 4 v.erase(iter); 5 } 因此vector中正确的删除的方法是: for(auto iter = v.begin(), iter!=v.end(); /*iter++*/) {

STL慎重选择删除元素的

 一.要删除容器中有特定值的全部对象 1.假设容器是vector.string或deque.则使用erase-remove习惯使用方法.比如: vector<int> c; c.erase(remove(c.begin(),c.end(),1963),c.end());//删除值是1963的元素 以下讲一下算法remove: template<classForwardIterator,class T> ForwardIteratorremove(ForwardIterator

Effective STL: 不同容器删除元素的方法

不同容器删除元素的方法 去除一个容器中有特定值的所有对象: 如果容器是vector.string或deque,使用erase-remove惯用法. 如果容器是list,使用list::remove. 如果容器是标准关联容器,使用它的erase成员函数. 去除一个容器中满足一个特定判定式的所有对象: 如果容器是vector.string或deque,使用erase-remove_if惯用法. 如果容器是list,使用list::remove_if. 如果容器是标准关联容器,写一个循环来遍历容器元素

JavaScript向select下拉框中添加和删除元素

JavaScript向select下拉框中添加和删除元素 1.说明 a   利用append()方法向下拉框中添加元素 b   利用remove()方法移除下拉框中最后一个元素 2.设计源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xm

给数组添加一个根据指定下标删除元素的方法、得到0-100的随机数不重复(js)、得到外联样式的css样式值

/** *删除数组指定下标或指定对象 */ Array.prototype.remove=function(obj){ for(var i =0;i <this.length;i++){ var temp = this[i]; if(!isNaN(obj)){ temp=i; } if(temp == obj){ for(var j = i;j <this.length;j++){ this[j]=this[j+1]; } this.length = this.length-1; } } }

Delphi中ListView中实现自定义删除功能的方法

Delphi中ListView中实现自定义删除功能的方法 第一种:有时删除文件会出现文件删不掉现象 if lvMain.InnerListView.ItemIndex <> -1 then begin // DoContextMenuVerb(lvMain.SelectedFolder, 'delete'); DoContextMenuVerbB(lvMain.Folders[lvMain.InnerListView.ItemIndex], 'delete'); 第二种:删除功能很强大,建议使