如何擦除C ++映射中的最后n个元素?

时间:2010-09-20 10:55:50

标签: c++ stl

nth element C++中找到std::map是否有一种简单明了的方法?特别是我正在寻找一种算法来擦除k中的最后map个元素。将迭代器检索到nth element并调用std::map::erase是有意义的。要求是复杂性不会受到影响 - 应该可以删除O(N)中的元素范围。

不应仅仅为了擦除元素而复制数据。例如,一种解决方案是将数据复制到std::vector,然后在std::nth_element上执行std::vector,然后在std::map::find找到迭代器,以便找出从中删除的位置

其他解决方案之一就是迭代std::map,维护要删除的元素数量的计数器变量。这会给O(n)。是否可以用for替换STL algorithm循环?

2 个答案:

答案 0 :(得分:9)

地图不会按索引提供比元素更好的线性访问,例如vectordeque。您可以使用std::advance执行此操作,但需要的时间与k成比例。如果k很小,它通常足够快 - 它基本上涉及跟随k指针。这是一个例子:

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

或者,如果您使用的是Boost,则可以使用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());
}

否则,您必须维护单独的索引,或使用其他容器。如果您没有过多地插入和删除元素,那么像排序vector这样的东西可能是合适的。

答案 1 :(得分:0)

修改:编辑原始帖子后答案不适用。