【发布时间】:2012-08-30 14:08:06
【问题描述】:
如何有效地从std::set 中选择随机元素?
std::set::iterator 不是随机访问迭代器。所以我不能像 std::deque 或 std::vector 那样直接索引随机选择的元素
我可以获取从 std::set::begin() 返回的迭代器,并在 [0,std::set::size()) 范围内随机增加它的次数,但这似乎做了很多不必要的工作。对于接近集合大小的“索引”,我最终会遍历内部树结构的整个前半部分,即使已经知道不会在那里找到该元素。
有更好的方法吗?
以效率的名义,我愿意将“随机”定义为 更少随机,而不是我可能用来在向量中选择随机索引的任何方法。称之为“合理随机”。
编辑...
下面有许多有见地的答案。
简短的版本是,即使你可以在 log(n) 时间内找到一个 特定 元素,你也找不到一个 任意 元素在那个时候通过std::set 接口。
【问题讨论】:
-
将集合的所有迭代器都扔到
std::vector中并从中随机选择? -
问:如果你想“访问一个随机值”,那么你一开始就不应该使用集合,对吗?我喜欢 Xeo 的建议:如果您想以不同方式访问元素,请使用不同的访问器(例如“将所有迭代器放入 std::vector”)。
-
@Xeo 这很聪明。你应该发布那个。
-
@Xeo 这会比在列表中递增直到达到随机索引更快吗?
-
如果随机性不是很重要,只要使用集合中的第一个元素即可。