c++ - 获取随机元素并将其删除

标签 c++ performance data-structures vector big-o

问题:我需要为一个容器获取一个随机元素,并将其从该容器中删除。容器不需要分类。 我不关心顺序。

  • Vector 可以在 O(1) 中获取随机元素,但仅在 O(N) 中删除它
  • List删除元素O(1)但只能随机取元素O(N)

所以我想到了制作一个自定义 vector 的想法,它允许您通过索引删除任何元素,复杂度为 O(1)+。 这个想法是交换最后一个元素和要删除的元素,然后交换 pop_back()。 如果您需要删除最后一个元素 - 只需 pop_back()。 vector 的顺序不会相同,但您会得到一个快速删除方法。

据我所知,与我的解决方案相比,双端队列的索引访问速度更慢,删除复杂性更差,但我不是 100% 确定。

我很好奇是否存在按索引或按值在 O(1)O(logN) 中随机访问和删除元素的数据结构?

最佳答案

您有解决方案,而且看起来非常好。用 C++ 编写它的惯用方法不是创建另一个类( don't inherit from std::vector ),而是编写一个函数:

template <typename T>
void remove_at(std::vector<T>& v, typename std::vector<T>::size_type n)
{
    std::swap(v[n], v.back());
    v.pop_back();
}

用法:

remove_at(v, 42);

这提供与 std::swap<T> 相同的异常保证.

现在,如果你想返回对象,并且你可以访问 C++11 编译器,你可以按以下方式进行。困难的部分是在所有情况下都提供基本的异常保证:

template <typename T>
T remove_at(std::vector<T>&v, typename std::vector<T>::size_type n)
{
    T ans = std::move_if_noexcept(v[n]);
    v[n] = std::move_if_noexcept(v.back());
    v.pop_back();
    return ans;
}

事实上,如果在移动操作期间抛出异常,您不希望 vector 处于无效状态。

关于c++ - 获取随机元素并将其删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9218724/

相关文章:

mysql - MySql 表中的简单计数 ID 需要很长时间

java - PixelGrabber 与 getRGB 哪个更快?

c - 出现段错误。不知道为什么

c++ - 使用 lambda 的 Boost 算法无法编译

c++ - 如何在不使用 break 的情况下退出 C++ 中的循环?

c# - .NET 中属性的性能开销

c++ - 排序数据结构,允许在排序键上重复,但在亚线性时间内替换另一个键上的重复项

C++括号匹配应用

c++ - 为什么 valarray 这么慢?

c++ - 如何设置 Code::Blocks 的目录?