c++ - 如何以 O(1) 的时间从 C++ 哈希表中随机检索元素

标签 c++ hashtable unordered-map random-access unordered-set

有没有一种方法可以在 O(1) 平均时间内从 C++ unordered_set 中随机检索元素?而不是做

std::unordered_set<int> s;
// initialize s
auto start = s.begin();
for (int i = 0; i < rand()%s.size()-1; ++i, ++start) {}
int randomNumber = *start;

更新:

我需要争取这个职位,所以我添加了我需要上述功能的原因。

我正在尝试实现一个迷宫生成器。不知何故,我需要一个支持的数据结构:

  1. 插入/删除时间复杂度为 O(1)
  2. 在 O(1) 时间内从数据结构中随机检索元素

std::vector 具有随机访问,但插入/删除成本较高

std::list 没有随机访问

std::set 支持 O(logN) 随机访问和 O(logN) 插入/删除,这很棒,但我的初始化是一个排序序列,很容易打破它的平衡.

所以我认为哈希表是最好的选择,但是随机检索一个元素将是不平凡的。

感谢您的宝贵时间。

最佳答案

您无法从 unordered_set 中选择随机元素在 O(1) 时间内。迭代器是 ForwardIterator s,不是RandomAccessIterator s。您将不得不使用不同的容器。要么 boost::container::flat_set<int> 或者自己编写一个类似 vector 的内容内部:

template <typename T>
class set_with_random_access
{
    std::vector<T*> vec;
    std::unordered_set<T> set;
};

为此,我们提供了使它们保持一致的功能,例如插入:

void insert(const T& value) {
    auto pr = set.insert(value);
    if (pr.second) {
        vec.push_back(&*pr.first);
    }
}

和随机性:

template <typename GEN>
T& random(GEN& gen) {
    std::uniform_int_distribution<size_t> dist(0, vec.size() - 1);
    return *vec[dist(gen)];
}

坦率地说,这需要做很多工作,所以可能会使用 boost 。

关于c++ - 如何以 O(1) 的时间从 C++ 哈希表中随机检索元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28055843/

相关文章:

c++ - 哪种数据结构最适合实现字典?

c++ - 在模板类中,如何处理基类的未指定对象数组?

c++ - boost::signals2 的绑定(bind)类成员函数

C++ 哈希链接函数

algorithm - 与条目数相关的哈希表应该初始化多大?

c++ - 列表迭代器不可取消引用

c++ - 将 unordered_map 设置为 unordered_map 的值

C++:std::unordered_map 保证是基于节点的吗?

c++ - 可以将一个语句分成多行吗?

c++ - printf 对待 *p++ 的方式与对待 p 的方式不同