multiset<> 里删除几个对象有没有快的方法?

damo_xu 2009-04-02 06:27:29
multiset<> 里删除几个对象有没有快的方法?
用简单的iterator ++遍历删除好像不行,因为删除后好像位置改变了。
...全文
205 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
M_S_D_N 2009-04-02
  • 打赏
  • 举报
回复
因为是multisets,所以使用erase(value)时可能会删除多个元素,也就可能刚好删除了下一个元素,导致之前得到的下一个元素迭代器失效。


it = itor++; // 此处得到下一个元素迭代器
if ((*it).条件满足)
{
v.push_back(*it);
mm.erase(*it);
}
M_S_D_N 2009-04-02
  • 打赏
  • 举报
回复
楼主可以这样改。。。

multiset <对象>::iterator it, itor = mm.begin();
while ( itor != mm.end() )
{
// it = itor++;
if ((*it).条件满足)
{
v.push_back(*it);
// mm.erase(*it);
mm.erase(it ++) ;
}
else
++ it ;
}
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hairetz 的回复:]
while( (iter=mm.find(3)) !=mm.end())
mm.erase( iter);
楼主什么问题?跟我在11楼写的有什么区别?你不是说不对吗?
[/Quote]

现在再看老兄11楼的代码就好理解了,关键当初我没注意到*iter和iter区别,
而且老兄用的是map,不存在遍历查找的问题。我是set,所以没仔细看。现在看确实是一样,还是多谢了。
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
找到原因了:
erase(*itor) 这个版本微软有一句这个注释:
// erase and count all that match _Keyval
就是把所有相同的键值全部删掉!!!

erase(itor)这个版本应该是红黑树写的,160多行,倒!!!

明天加分结贴。多谢诸位,尤其是Waiting4you兄台啦。
最后一个8卦问题问问Waiting4you兄台:你是怎么注意到这2个版本的区别的?嘿嘿。
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 damo_xu 的回复:]
牛人!!!
erase(itor)确实没有问题,erase(*itor)有bug。
为什么?

正在测试中。。。。。多谢多谢
[/Quote]

while( (iter=mm.find(3)) !=mm.end())
mm.erase( iter);

楼主什么问题?跟我在11楼写的有什么区别?你不是说不对吗?
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
牛人!!!
erase(itor)确实没有问题,erase(*itor)有bug。
为什么?

正在测试中。。。。。多谢多谢
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 Waiting4you 的回复:]
貌似我看懂楼主的意思了,你可以这样删除:
itor=mm.erase(itor);//使用这个版本的erase
[/Quote]

呵呵,多谢了,总算有人看懂了!!!明天再加分给你,呵呵。

问题1》老兄和我在3楼写的程序差不多啊?
问题2》erase(itor)这个版本安全?erase(*itor)不安全?

这个程序我认为和我写的差不多,我认为删除头尾的值还行,可是要删除中间的某个值,就不安全了吧?
原因是删除以后,itor++这句命令,不能保证还正确,而且ms.end()好像也变了吧?
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hairetz 的回复:]
只找一次也可以.
mm.erase(iter,iter+sz_max);
[/Quote]

十分不懂。

删除了以后,set里的对象位置都变了,怎么办?
Waiting4you 2009-04-02
  • 打赏
  • 举报
回复
貌似我看懂楼主的意思了,你可以这样删除:

int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
multiset<int> mm;
for(int i=0; i<10; i++)
{
mm.insert(i);
mm.insert(i);
}

multiset<int>::iterator itor = mm.begin();
while ( itor != mm.end() )
{
if (*itor == 0)//如果itor是0,显示并删除
{
//v.push_back(*itor);
cout << *itor << ' ';
itor = mm.erase(itor);//使用这个版本的erase
}
else
++itor;
}
cout << endl;
copy(mm.begin(), mm.end(), ostream_iterator<int>(cout, " ")); //显示set里的数据
return 0;
}
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 damo_xu 的回复:]
引用 8 楼 hairetz 的回复:
好像你没有弄懂我的意思?
比如从mm中提出3,9,23,这几个位置的对象,并保存到应该vector里,怎么写代码?

这跟删除有联系不?

比如对3操作.

用multimap <int,string>::iterator iter=mm.find(3);
multimap <int,string>::size_type sz_max,sz_index;
sz=mm.count(3);
for(sz_index=0;sz_index!= sz_max;++ sz_index,++iter)
vec.push_back(iter->second); /…
[/Quote]

只找一次也可以.

mm.erase(iter,iter+sz_max);
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hairetz 的回复:]
好像你没有弄懂我的意思?
比如从mm中提出3,9,23,这几个位置的对象,并保存到应该vector里,怎么写代码?

这跟删除有联系不?

比如对3操作.

用multimap <int,string>::iterator iter=mm.find(3);
multimap <int,string>::size_type sz_max,sz_index;
sz=mm.count(3);
for(sz_index=0;sz_index!= sz_max;++ sz_index,++iter)
vec.push_back(iter->second);                //3对应的所有second数据全存入vector
[/Quote]

噢,对不起,是我的mm引起了大家的误会,呵呵,郑重道歉。
我的原题是说multiset,关键没有这个索引,而且到底是哪个位置必须得到对象后才能知道。
麻烦老兄在看看我原来的代码。如果没有别的办法,只能每删除一个后,重新再找再删。

  • 打赏
  • 举报
回复
删除就更简单了.
multimap <int,string>::iterator iter;
while( (iter=mm.find(3)) !=mm.end())
mm.erase( iter);
wxgiter 2009-04-02
  • 打赏
  • 举报
回复
STL的操作只要用合适了就够快了。。
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 damo_xu 的回复:]
大家还是没有明白我说什么?

对不起,我表达能力太差了。

那么我问>
怎么剔除一个mm里某些满足条件的对象,而剔除前要保存这个对象?

clear() ? 全删光了?
选择范围就.begin或者.end? 我在用啊!
具体删除用erase键值? 我也在用啊!关键我是问删完了怎么找下一个对象?
[/Quote]

++iter就可以了,map都是hash过的,本身已经排序,iter找到第一个元素,后面的符合要求的都在一起.
  • 打赏
  • 举报
回复
好像你没有弄懂我的意思?
比如从mm中提出3,9,23,这几个位置的对象,并保存到应该vector里,怎么写代码?

这跟删除有联系不?

比如对3操作.

用multimap<int,string>::iterator iter=mm.find(3);
multimap<int,string>::size_type sz_max,sz_index;
sz=mm.count(3);
for(sz_index=0;sz_index!= sz_max;++ sz_index,++iter)
vec.push_back(iter->second); //3对应的所有second数据全存入vector
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
大家还是没有明白我说什么?

对不起,我表达能力太差了。

那么我问>
怎么剔除一个mm里某些满足条件的对象,而剔除前要保存这个对象?

clear() ? 全删光了?
选择范围就.begin或者.end? 我在用啊!
具体删除用erase键值? 我也在用啊!关键我是问删完了怎么找下一个对象?
xuruichen 2009-04-02
  • 打赏
  • 举报
回复
迭代起器当然不行.
你全部清空就clear.

选择范围就.begin或者.end


iterator erase(iterator first, iterator last);


还是比较快的。
damo_xu 2009-04-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hairetz 的回复:]
晕,迭代起器当然不行.
你全部清空就clear.
选择范围就.begin或者.end
具体删除用erase键值,这样还不能满足你?
[/Quote]

好像你没有弄懂我的意思?
比如从mm中提出3,9,23,这几个位置的对象,并保存到应该vector里,怎么写代码?
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 damo_xu 的回复:]

multiset <对象>::iterator it, itor = mm.begin();
while ( itor != mm.end() )
{
it = itor++;
if ((*it).条件满足)
{
v.push_back(*it);
mm.erase(*it);
}
}

这就是我说得,删除堆的东西,这样遍历不行。
[/Quote]

晕,迭代起器当然不行.
你全部清空就clear.

选择范围就.begin或者.end

具体删除用erase键值,这样还不能满足你?
damo_xu 2009-04-02
  • 打赏
  • 举报
回复

multiset<对象>::iterator it, itor = mm.begin();
while ( itor != mm.end() )
{
it = itor++;
if ((*it).条件满足)
{
v.push_back(*it);
mm.erase(*it);
}
}

这就是我说得,删除堆的东西,这样遍历不行。
加载更多回复(2)

65,211

社区成员

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

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