【问题标题】:erase max element from STL set从 STL 集中擦除最大元素
【发布时间】:2010-07-26 20:33:27
【问题描述】:

这是我之前提出的问题 (Complexity of STL max_element) 的后续跟进。

我想基本上从集合中弹出最大元素,但我遇到了问题。

这大概是我的代码:

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() >> 0 时它失败了。

【问题讨论】:

  • *objectSet.rbegin(); 是错字吗?您要取消对集合的引用吗?
  • 不,它是被取消引用的迭代器。圆点比星星更紧密。

标签: c++ stl set


【解决方案1】:

您已经很接近了,但是您在迭代器分配中尝试做的太多了。您将 post-decrement 运算符应用于 end 返回的任何内容。我不确定那是做什么的,但几乎可以肯定这不是你想要的。将end的结果赋值给i然后递减得到集合的最后一个元素。

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

【讨论】:

    【解决方案2】:

    你需要这样做:

    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;
    }
    

    【讨论】:

      【解决方案3】:

      声明

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

      表示“将 end() 分配给 i,然后递减一个即将被丢弃的临时变量”。换句话说,它与set&lt;Object&gt;::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())

      【讨论】:

      • 我确实尝试了 rbegin().base(),但无济于事。
      • rbegin().base()end() 相同。
      猜你喜欢
      • 2013-01-28
      • 2013-04-07
      • 2020-11-06
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      相关资源
      最近更新 更多