如何删除 C++ 中的最后 n 个元素地图?

发布于 2024-09-24 07:08:20 字数 535 浏览 0 评论 0原文

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

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独自←快乐 2024-10-01 07:08:21

映射无法通过索引提供比线性更好的元素访问,例如 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());
}

否则,您将必须维护单独的索引,或使用不同的容器。如果您不插入和删除太多元素,则类似排序向量之类的东西可能是合适的。

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.

云醉月微眠 2024-10-01 07:08:21

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

Edit: Answer not applicable after edit of original post.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文