【问题标题】:C++ multisets: removing the last elementC ++多重集:删除最后一个元素
【发布时间】:2013-10-28 10:24:55
【问题描述】:

如何从多重集中删除最后一个元素。我尝试将反向迭代器传递给擦除函数,但这是不允许的。有什么建议吗?

【问题讨论】:

标签: c++ multiset


【解决方案1】:

每个reverse_iterator 都有一个base() 函数,它返回“标准化”迭代器。你可以这样使用它:

auto e = ms.rbegin();
ms.erase((++e).base());

我们必须在获取底层迭代器之前增加e,因为基本迭代器指的是下一个 到reverse_iterator 指向的元素的元素。

另一种解决方案是使用std::prev函数:

ms.erase(std::prev(ms.end())); // since C++11

如果 C++11 不适合您,您可以自己实现:

// copy-pasted from cppreference
template<class BidirIt>
BidirIt prev(BidirIt it, 
             typename std::iterator_traits<BidirIt>::difference_type n = 1)
{
    std::advance(it, -n);
    return it;
}

它比第一个更简单,但我留下了两个解决方案,因为之前我错误地描述了第一个示例。

【讨论】:

  • 酷,我不知道。或者,std::prev(std::end(ms))
  • @chris,请再看一遍答案。我的第一个解释是不正确的。
  • @很快我尝试了第二个.. 它给出了一个错误,说 prev 不是 std 的成员
  • 这里std::prevoperator-- 有什么好处吗?
【解决方案2】:

因为多集擦除函数采用常规的迭代器。所以如果你想删除最后一个元素,你应该这样做。

//in C++11
multiset.erase(std::prev(multiset.end()));
//in C++98 
multiset.erase(--multiset.end()); 

【讨论】:

    【解决方案3】:

    你可以试试下面的代码:

    multiset<int> mySet;
    

    读入一些整数.....

    multiset<int>::reverse_iterator rit;
    rit = mySet.rbegin();
    
    mySet.erase((++rit).base());
    

    .rbegin() 函数返回一个指向集合末尾的反向迭代器,然后 rit 递增,因为基函数当前指向我们想要的值旁边的值(这部分归功于 @soon,在他的回答中)。然后,erase() 函数会擦除参数中的元素。

    希望这会有所帮助。 =)

    【讨论】:

    • @很快我似乎已经修复了它。感谢您指出我的错误。
    【解决方案4】:

    如果你只想删除一个元素,那么你可以写

    if ( !ms.empty() ) ms.erase( std::prev( ms.end() ) );
    

    如果要删除给定键等于最后一个键的所有元素,则可以编写

    if ( !ms.empty() )
    {
        auto p = ms.equal_range( *std::prev( ms.end() ) );
        ms.erase( p.first, p.second );
    }
    

    最后,如果你想删除除一个之外的所有重复项,那么你可以编写

    if ( !ms.empty() )
    {
        auto p = ms.equal_range( *std::prev( ms.end() ) );
        ms.erase( std::next( p.first ), p.second );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 2020-01-28
      • 1970-01-01
      • 2012-08-20
      • 2010-12-11
      相关资源
      最近更新 更多