【发布时间】:2015-03-19 07:13:27
【问题描述】:
有没有办法在 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;
更新:
我需要为职位而战,所以我添加了我需要上述功能的理由。
我正在尝试实现一个迷宫生成器。不知何故,我需要一个支持的数据结构:
- O(1) 中的插入/删除
- 在 O(1) 中从数据结构中随机检索一个元素
std::vector 可以随机访问,但是插入/删除开销很大
std::list 没有随机访问权限
std::set 支持 O(logN) 随机访问和 O(logN) 插入/删除,这很棒,但我的初始化是一个排序序列,很容易破坏它的平衡.
所以我认为哈希表是最好的选择,但是随机检索一个元素将是不平凡的。
感谢您的宝贵时间。
【问题讨论】:
-
什么意思?这 是 O(1) 预期的(尽管它是错误的代码,因为它错误地使用了
rand,并且无论如何,rand应该被视为弃用,以支持<random>header)。此外,“random access” 通常还有其他含义。 -
“随机访问”是指“选择集合中的一个随机元素吗?”
-
在这段代码中,最坏的情况是
rand()%s.size()总是返回一个大于i的数字。这意味着您将访问n元素,所以这显然是O(n)。这可能不是你想要的,但它是你会得到的。 -
@RafaelLerm 请注意,它与
i进行比较,但增加了start。我假设 OP 实际上想要 做的是别的事情,即选择 n 个随机元素…… -
我看到了,但是
i仍然是循环的条件,所以我认为最坏的情况仍然成立。我还没有决定OP想要什么。它要么选择 n 个随机元素,在这种情况下 O(1) 问题只是愚蠢的,要么他想得到一个随机元素。
标签: c++ hashtable unordered-map random-access unordered-set