【发布时间】:2013-10-28 10:24:55
【问题描述】:
如何从多重集中删除最后一个元素。我尝试将反向迭代器传递给擦除函数,但这是不允许的。有什么建议吗?
【问题讨论】:
如何从多重集中删除最后一个元素。我尝试将反向迭代器传递给擦除函数,但这是不允许的。有什么建议吗?
【问题讨论】:
每个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))
std::prev 比operator-- 有什么好处吗?
因为多集擦除函数采用常规的迭代器。所以如果你想删除最后一个元素,你应该这样做。
//in C++11
multiset.erase(std::prev(multiset.end()));
//in C++98
multiset.erase(--multiset.end());
【讨论】:
你可以试试下面的代码:
multiset<int> mySet;
读入一些整数.....
multiset<int>::reverse_iterator rit;
rit = mySet.rbegin();
mySet.erase((++rit).base());
.rbegin() 函数返回一个指向集合末尾的反向迭代器,然后 rit 递增,因为基函数当前指向我们想要的值旁边的值(这部分归功于 @soon,在他的回答中)。然后,erase() 函数会擦除参数中的元素。
希望这会有所帮助。 =)
【讨论】:
如果你只想删除一个元素,那么你可以写
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 );
}
【讨论】: