从STL集中擦除最大元素

时间:2010-07-26 20:33:27

标签: c++ stl set

这是对我之前的问题(Complexity of STL max_element)的跟进。

我想基本上从一组中弹出max元素,但我遇到了问题。

这大致是我的代码:

set<Object> objectSet;

Object pop_max_element() {
    Object obj = *objectSet.rbegin();
    set<Object>::iterator i = objectSet.end()--; //this seems terrible
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
    return obj;
}

早些时候我试过objectSet.erase(objectSet.rbegin());,但编译器抱怨没有匹配的函数(我猜它不喜欢reverse_iterator)。我知道没有检查空集,但是当objectSet.size()&gt;&gt;时它失败了。 0

3 个答案:

答案 0 :(得分:9)

你非常接近,但你试图在迭代器分配中做太多。您将后递减运算符应用于任何end返回。我不确定那是什么,但几乎肯定不是你想要的。将end的结果分配给i,然后然后递减它以获取该集合的最后一个元素。

set<Object>::iterator i = objectSet.end();
--i;
Object obj = *i;
objectSet.erase(i);
return obj;

答案 1 :(得分:5)

你需要这样做:

set<Object> objectSet;

Object pop_max_element() {
    Object obj = *objectSet.rbegin();
    set<Object>::iterator i = --objectSet.end(); // NOTE: Predecrement; not postdecrement.
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
    return obj;
}

答案 2 :(得分:5)

声明

set<Object>::iterator i = objectSet.end()--;

表示'为...分配end()然后递减一个即将丢弃的临时变量'。换句话说,它与set<Object>::iterator i = objectSet.end();相同,我相信你会认识到你无法擦除end(),因为它指向一个结尾。请改用这样的东西:

assert(!objectSet.empty()); // check there is something before end
set<Object>::iterator i = objectSet.end();
--i;
objectSet.erase(i);

并且没关系,这是一种合法的方式来为一个集合重现.back()

此外,反向迭代器有一个base()成员转换为普通迭代器,我想你只能删除正常的迭代器 - 试试objectSet.erase(objectSet.rbegin().base())