How can I select a random element in an std::set?
I naively tried this:
int GetSample(const std::set& s) {
double r =
A hypothesized in a comment above, it can be done in O(log(n)) (vs O(n) for std::advance) without a vector (using O(n) more space) by using the method I describe here.
Essentially, you :
it on it*(it++) or *(set.begin()) if it at the endn.b : As pointed out by Aaron the element is not chosen uniformly at random. You need to build the random element with the same distribution than the elements in the set to approach a uniform polling.
davidhigh already gave the solution with a vector but there is a problem because when you pop an element of your stack, you will have to perform a linear search in O(n) or you can rebuild your vector each time you want to retrieve a random element but that is O(n) too.
To avoid this problem and keep the insert/delete to O(log n), you can keep an std::unordered_set and use a similar method to the first solution to get a random element in O(1).
p.s : If your elements are large you can use an unordered set of pointers (with a modified hasher) to spare some memory.