如何在std :: set中选择一个随机元素?

Fra*_*ank 29 c++ iterator set

如何选择一个随机元素std::set

我天真地试过这个:

int GetSample(const std::set<int>& s) {
  double r = rand() % s.size();
  return *(s.begin() + r); // compile error
}
Run Code Online (Sandbox Code Playgroud)

但这operator+是不允许的.

xto*_*ofl 44

你可以使用这个std::advance方法.

#include <set>
#include <algorithm>

int main() {
  using namespace std;
  // generate a set...
  set<int> s;
  for( int i = 0; i != 10; ++i ) s.insert(i);
  auto r = rand() % s.size(); // not _really_ random
  auto n = *select_random(s, r);
}
Run Code Online (Sandbox Code Playgroud)

  • 可能是O(logN).std :: set存储在某种树中,可能有一个解决方案只能在其中一个分支上发生,并且已完成. (21认同)
  • 任何解决方案都是O(N).证明留作练习,暗示:在恒定时间内可以达到std :: set的多少元素? (4认同)
  • @Kiscsirke 您是对的,使用平衡搜索树,您可以使用 O(log(N)) 进行插入、删除和随机访问。然而,后者要求节点存储他们的左边或右边有多少孩子。这需要在插入、移除和重新平衡期间更新。由于 `std::set` 和 `std::map` 对用户隐藏了树内部结构,因此它们不能用于实现此目的。我最终实现了自己的搜索树。绝对有可能获得 O(log(N)) 查找。 (2认同)