How to erase the last n elements in the C++ map?
Is there a nice and simple way to find nth element开发者_开发百科
in C++
std::map
? Particularly I'm looking for an algorithm to erase the last k
elements from the map
. That would make sense to retrieve the iterator to the nth element
and call std::map::erase
. The requirement is that complexity doesn't suffer - that should be possible to erase the element range in O(N)
.
Copy of the data shouldn't be made just to erase the elements. For example one solution is to copy the data into std::vector
, then do std::nth_element
on std::vector
, and then std::map::find
to find the iterator in order to find out where to erase from.
One of other solutions is to just iterate over std::map
maintaining a counter variable on the number of elements to remove. That would give O(n)
. Is that possible to replace the for
loop with STL algorithm
?
Maps don't provide better-than-linear access to elements by index, like vector
or deque
. You can do this using std::advance
, but it takes time that is proportional to k
. If k
is small, it will often be fast enough - it basically involves following k
pointers. Here's an example:
template<typename Map>
void erase_last_elements(Map & map, ptrdiff_t k)
{
assert(k >= 0);
assert(map.size() >= (size_t)k);
typename Map::iterator i = map.end();
std::advance(i, -k);
map.erase(i, map.end());
}
Alternatively, if you're using Boost, you can use boost::prior
:
template<typename Map>
void erase_last_elements(Map & map, ptrdiff_t k)
{
assert(k >= 0);
assert(map.size() >= (size_t)k);
typename Map::iterator i = boost::prior(map.end(), k);
map.erase(i, map.end());
}
Otherwise, you'll have to maintain a separate index, or use a different container. Something like a sorted vector
might be appropriate, if you don't insert and remove elements too much.
Edit: Answer not applicable after edit of original post.
精彩评论