开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜