vector::erase用法

阿浪 2010-12-24 10:56:41
今天在网上看了这么一段
有个vector


vector<AA> vaa;

一个list


list<int> intList;
现在需要执行这样的操作, 删除vaa里所有成员变量n在intList里的所有元素.那么, 应该怎么做呢?我们可以有下列选择:
1 手写循环
仿照list的删除方法.


vector<AA>::iterator ite = vaa.begin();
for (; ite != vaa.end(); )
{
if (find(intList.begin(), intList.end(),ite->n) != intList.end())
vaa.erase(++ite);
else
++ite;
}

一运行就会发现不行了, vector的erase的特点是, 被删除的元素和之后的所有元素的iterator都失效了, 即使保存了后面一个iterator, 也不能继续遍历了

感觉好像是错的

vector<AA>::iterator ite = vaa.begin();
for (; ite != vaa.end(); )
{
if (find(intList.begin(), intList.end(),ite->n) != intList.end())
ite = vaa.erase(ite);
else
++ite;
}



不就可以了么?
我写了一个代码试了一下,好像没啥问题。各位看法?
...全文
580 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
lifuhua6 2012-02-23
  • 打赏
  • 举报
回复
一、
vector<AA>::iterator ite = vaa.begin();
for (; ite != vaa.end(); )
{
if (find(intList.begin(), intList.end(),ite->n) != intList.end())
ite = vaa.erase(ite);
else
++ite;
}

二、
vector<AA>::iterator ite = vaa.begin();
for (; ite != vaa.end(); )
{
if (find(intList.begin(), intList.end(),ite->n) != intList.end())
{
vaa.erase(remove(vaa.begin(), vaa.end(), *ite));
}
}
阿浪 2010-12-26
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 qq120848369 的回复:]
平安夜,你给了大家一个悲剧的帖子,行了吧,你自己也长脑子,你看看原作者的代码,你觉得他对就对,错就错.

我再提示你一点,你看你的ite是哪个容器的迭代器,再看看你用哪个容器erase了ite,我不说了,你是高手.
[/Quote]
这哥们在说啥啊,我还是看不懂。。。
我只是改他一行代码啊


vaa.erase(++ite);

改成了

ite =vaa.erase(ite);

然后容器或者迭代器就变了?
qq120848369 2010-12-24
  • 打赏
  • 举报
回复
平安夜,你给了大家一个悲剧的帖子,行了吧,你自己也长脑子,你看看原作者的代码,你觉得他对就对,错就错.

我再提示你一点,你看你的ite是哪个容器的迭代器,再看看你用哪个容器erase了ite,我不说了,你是高手.
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 qq120848369 的回复:]
我说你错,你就完全错,你不用不服,你写的代码没有一个地方是对的.
[/Quote]

道行,你工作的时候也样么。。。不看题目是啥?

再者,你发代码,虽然你解决了问题,却绕开了问题。

其三,“ite永远都要++好不好”你的
 iterList=lst.erase(iterList);
要没有加加。

最后,“我说你错,你就完全错,”我错在哪里?请兄不吝高教。
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 qq120848369 的回复:]
我说你错,你就完全错,你不用不服,你写的代码没有一个地方是对的.
[/Quote]

你也是完全不看的。。。那不是我写的。。。我都晕倒了。。。
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 taodm 的回复:]
楼主啊,买本《effective stl》吧
[/Quote]
而且,哥们,你看清一问,我问的是啥。

我在网上找了一教程,我看了一下他其他的文章,发现他水平比较高。

但这个教程里,他说某种情行下不能用erace,说了一个例子,就是我上发的第一个代码 ,

但我想他用得可能有错,因为我很容易就能达到,并了测试了一下自己写的代码。

再此由于我觉得发教程的人,水平高于我,所以我想,我的代码可能有某些副做用,所以我来问问。
qq120848369 2010-12-24
  • 打赏
  • 举报
回复
我说你错,你就完全错,你不用不服,你写的代码没有一个地方是对的.
qq120848369 2010-12-24
  • 打赏
  • 举报
回复
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>

using namespace std;

int main()
{
int arrVec[]={1,2,3};
int arrLst[]={2,2,1,4,3,2,6};

vector<int> vec(arrVec,arrVec+3);
list<int> lst(arrLst,arrLst+7);

for(vector<int>::const_iterator iter=vec.begin();iter!=vec.end();++iter)
{
list<int>::iterator iterList=lst.begin();

while( ( iterList=find(iterList,lst.end(),*iter) )!=lst.end() )
{
iterList=lst.erase(iterList);
}
}

for(list<int>::iterator iter=lst.begin();iter!=lst.end();++iter)
{
cout<<*iter<<" ";
}

cout<<endl;

return 0;
}
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lijing_lj928 的回复:]
vector 的erase函数会是删除的迭代器后后续的迭代器都失效,而且由于vertor内部是连续的内存空间,删除元素后,会讲后边的元素往前移,所以楼主的第一种方法有问题,而且楼主的一个从算法本来就有问题,vaa.erase(++ite);是删除的是ite后边的一个元素

要达到功能可以用LZ的第二个方法,erase函数,返回的是删除元素的下一个位置的迭代器
[/Quote]

大哥,你看清,我在问什么问题么?
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 taodm 的回复:]
楼主啊,买本《effective stl》吧
[/Quote]
我在CSDN这么久了,就最两种人。。。

哥们你就是其中一种,不过我问啥问题,问得多么小,都会马上有人告诉我看什么书,我们一般人都不是大 牛,问个问题,只是想要一个明确的答案。因为我不能和老板说,阿这个问题,我要来年七月,看完了《effective stl》再来解决。

再一种人就复制了一套MSDN上来。。。如果看这玩意 就管用,《核心编程》的价值。。。
Arthur-LJ 2010-12-24
  • 打赏
  • 举报
回复
vector 的erase函数会是删除的迭代器后后续的迭代器都失效,而且由于vertor内部是连续的内存空间,删除元素后,会讲后边的元素往前移,所以楼主的第一种方法有问题,而且楼主的一个从算法本来就有问题,vaa.erase(++ite);是删除的是ite后边的一个元素

要达到功能可以用LZ的第二个方法,erase函数,返回的是删除元素的下一个位置的迭代器
luciferisnotsatan 2010-12-24
  • 打赏
  • 举报
回复
vector用的是平摊法。添加或者删除元素时,都有可能新开一块空间,然后把现有空间里的元素整个复制过去,再释放现有空间。(理论上是这样子的,实际就得看代码怎么写的了)
不管前++,后++,重新分配后,原空间就不存在了,迭代器肯定失效。要用erase返回的才行
gules 2010-12-24
  • 打赏
  • 举报
回复
后置++法是对于关联式容器的删除元素有效;
对于vector、deque、string则使用 ite = vaa.erase(ite); 是正确的(用于标准序列式容器,不能用于关联式容器,因为关联式容器erase的返回值是void)。
taodm 2010-12-24
  • 打赏
  • 举报
回复
楼主啊,买本《effective stl》吧
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qq120848369 的回复:]
程序本身设计都是错的,ite永远都要++好不好,你搞清楚ite是谁的迭代器没.
[/Quote]
小段小代码,说一个例子,谈不以设计上吧? “ite永远都要++好不好”。。。不敢苟同啊。。。。
qq120848369 2010-12-24
  • 打赏
  • 举报
回复
程序本身设计都是错的,ite永远都要++好不好,你搞清楚ite是谁的迭代器没.
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 chlaws 的回复:]
C/C++ code

vector<AA>::iterator ite = vaa.begin();
for (; ite != vaa.end(); )
{
if (find(intList.begin(), intList.end(),ite->n) != intList.end())
vaa.erase(ite++);……
[/Quote]
晕倒了。。。你们都是这样写程序的么?根本不看要求。。上来就写?
chlaws 2010-12-24
  • 打赏
  • 举报
回复

vector<AA>::iterator ite = vaa.begin();
for (; ite != vaa.end(); )
{
if (find(intList.begin(), intList.end(),ite->n) != intList.end())
vaa.erase(ite++);
else
++ite;
}

阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 gules 的回复:]
我知道你在说什么,你自己先试试吧。
前置++与后置++是很大区别的!
[/Quote]
你那个是不对了,这里我不也想研究前置和后置。

我想研究是我引用代码和我的代码。我认为他的结论是不对的。
阿浪 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gules 的回复:]
是的,erase使vector的原有迭代器失效,可改写为:
vaa.erase(ite++); // 可利用后置++先返一个临时对象,再++来解决失效问题。
[/Quote]

vector<int> mveci;
mveci.push_back(1);
mveci.push_back(2);
mveci.push_back(3);
for (vector<int>::iterator citer = mveci.begin();citer != mveci.end(); )
{
if (2 == *citer)
{
mveci.erase(citer++);
}
else
citer++;
}



运行不了,错的。erase 后,大概重新构造了,以前的结点已经没用了。必须重新赋值。
加载更多回复(3)

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧