如何从C容器中精确获取一个随机且独特的元素?
- 内容介绍
- 文章标签
- 相关推荐
本文共计321个文字,预计阅读时间需要2分钟。
从STL范围获取[伪]随机元素的好方法是使用std::random_shuffle。例如,可以这样操作:
cppstd::random_shuffle(c.begin(), c.end());
然后从c.begin()获取我的随机元素。但如果你想要一个const容器中的随机元素,或者你想要做一些其他事情,你可以考虑以下方法:
cppstd::vector vec={1, 2, 3, 4, 5};std::random_shuffle(vec.begin(), vec.end());
const auto& randomElement=vec[0]; // 获取随机元素
从STL范围获取[伪]随机元素的好方法是什么?我能想到的最好的是做std :: random_shuffle(c.begin(),c.end())然后从c.begin()获取我的随机元素.
但是,我可能想要一个const容器中的随机元素,或者我可能不想要完全洗牌的成本.
有没有更好的办法?
这里使用%的所有答案都是不正确的,因为rand()%n会产生有偏差的结果:想象RAND_MAX == 5且元素数是4.然后你会得到两倍数字0和1而不是数字2或3.一个正确的方法是:
template <typename I> I random_element(I begin, I end) { const unsigned long n = std::distance(begin, end); const unsigned long divisor = (RAND_MAX + 1) / n; unsigned long k; do { k = std::rand() / divisor; } while (k >= n); std::advance(begin, k); return begin; }
另一个问题是std :: rand只假设有15个随机位,但我们在这里会忘记这一点.
本文共计321个文字,预计阅读时间需要2分钟。
从STL范围获取[伪]随机元素的好方法是使用std::random_shuffle。例如,可以这样操作:
cppstd::random_shuffle(c.begin(), c.end());
然后从c.begin()获取我的随机元素。但如果你想要一个const容器中的随机元素,或者你想要做一些其他事情,你可以考虑以下方法:
cppstd::vector vec={1, 2, 3, 4, 5};std::random_shuffle(vec.begin(), vec.end());
const auto& randomElement=vec[0]; // 获取随机元素
从STL范围获取[伪]随机元素的好方法是什么?我能想到的最好的是做std :: random_shuffle(c.begin(),c.end())然后从c.begin()获取我的随机元素.
但是,我可能想要一个const容器中的随机元素,或者我可能不想要完全洗牌的成本.
有没有更好的办法?
这里使用%的所有答案都是不正确的,因为rand()%n会产生有偏差的结果:想象RAND_MAX == 5且元素数是4.然后你会得到两倍数字0和1而不是数字2或3.一个正确的方法是:
template <typename I> I random_element(I begin, I end) { const unsigned long n = std::distance(begin, end); const unsigned long divisor = (RAND_MAX + 1) / n; unsigned long k; do { k = std::rand() / divisor; } while (k >= n); std::advance(begin, k); return begin; }
另一个问题是std :: rand只假设有15个随机位,但我们在这里会忘记这一点.

