这个问题增加了约束。
我愿意允许不统一的选择,只要不偏不倚。
鉴于“集合通常实现为二叉搜索树”,我希望他们会包含某种用于平衡的深度或大小信息,我希望您可以对树进行某种加权随机游走。但是我不知道有任何远程便携式方法可以做到这一点。
编辑:约束不适用于摊销时间。
This question with an added constraint.
I'm willing to allow not-uniform selection as long as it's not to lop sided.
Given that "sets are typically implemented as binary search trees" and I expect they will contain some kind of depth or size information for balancing, I would expect you could do some sort of weighted random walk of the tree. However I don't know of any remotely portable way to do that.
Edit: The constraint is NOT for the amortized time.
发布评论
评论(5)
引入大小等于 set 的数组。使数组元素保存集合中每个元素的地址。生成以数组/集合大小为界的随机整数
R
,在由R
索引的数组元素中选取地址并取消引用它以获取集合的元素。Introduce array with size equal to set. Make array elements hold addresses of every element in set. Generate random integer
R
bounded by array/set size, pick address in array's element indexed byR
and dereference it to obtain set's element.我不知道如何仅使用 std::set 来完成此操作,因此您可能需要不同的数据结构。正如维克多·索罗金(Victor Sorokin)所说,你可以将集合与向量组合起来。使用
map
和vector
代替::迭代器>
。每个键的值都是向量的索引,向量的每个元素都指向映射元素。向量元素没有特定的顺序。添加元素时,将其放在向量的末尾。当删除一个元素并且它不是向量中的最后一个元素时,请将最后一个元素移动到已删除元素的位置。set
。映射I don't see how to do it with just
std::set
, so you probably need a different data structure. Like Victor Sorokin said, you can combine a set with a vector. Instead ofset<T>
, usemap<T, size_t>
, plusvector< map<T, size_t>::iterator >
. The value for each key is an index into the vector, and each element of the vector points back to the map element. The vector elements have no particular order. When you add an element, put it at the end of the vector. When you remove an element and it's not the last one in the vector, move the last element to the deleted element's position.如果您知道集合中元素的分布,则可以随机选择键(具有相同的分布)并使用
std::set::lower_bound
。不过,这样的情况有很多。IF you know the distribution of the elements in the set, you can randomly select key (with that same distribution) and use
std::set::lower_bound
. That's a lot of if though.您可以使用此构造函数来制作地图的随机排序副本
..并传递一个比较键的哈希值(或其他一些确定性传播函数)的比较器。然后根据这个新的值获取“最小”键地图。
您可以构建一次地图,然后在对“随机”元素的多个请求中分摊成本。
You may be able to make a randomly-ordered copy of the map by using this constructor
..and passing a comparator that compares hashes of the keys (or some other deterministic spreading function.) Then take the "smallest" keys according to this new map.
You could construct the map once and amortize the cost across several requests for a "random" element.
对于 std::unordered_set; s:
1) 在
min(s)..max(s)
中取随机R
2) if
R
in>s
:返回 R3)
对于有序集 (std::set),概率取决于元素之间的距离。 unordered_set 通过哈希随机化。
我希望这能有所帮助。
PS 将
std::set
转换为std::set>
(其中对中的第一个元素是第二)使该方法适用于任何可哈希的 V。For
std::unordered_set<int> s
:1) take random
R
inmin(s)..max(s)
2) if
R
ins
: return R3)
For ordered set (std::set) probability would depend on distance between elements. unordered_set is randomized by hash.
I hope this can help.
PS converting
std::set<V>
intostd::set<std::pair<int, V>>
(where first element in pair is a hash of second) makes this method suitable for any hashable V.