我正在尝试玩具sample
程序:
map<int, char> foo { { 1, 'a' }, { 2, 'b' }, { 3, 'c' } };
vector<pair<decltype(foo)::key_type, decltype(foo)::mapped_type>> bar(size(foo));
sample(begin(foo), end(foo), begin(bar), size(foo), mt19937{ random_device{}() });
但bar
总是按顺序包含foo
的内容。这是一个gcc实现问题,还是我一再不幸?
抽样是关于返回更大人口的一些子集。
它不是以随机顺序或任何其他顺序返回元素。它可以,但那并不是它的真正含义。
cppreference暗示在此声明中订购:
仅当PopulationIterator满足ForwardIterator的要求时,该算法才是稳定的
这里的“稳定”意味着它将以与输入相同的顺序返回结果,因此使用ForwardIterator保证顺序不是随机的。相关:What is stability in sorting algorithms and why is it important?
这也是有道理的,因为,与注释中提到的类似,为了高效,您首先需要确定要选择哪些元素,然后通过迭代器并选择元素,因为您只能迭代一个方向到另一个方向。因此,将元素保持在相同的顺序应该是微不足道的。
至于何时不使用ForwardIterator,它无法保证订单的方式。因此,即使它看起来似乎是随机排序的,依靠这个也是不明智的,因为排序的随机性可能依赖于实现,它可能有也可能没有高entropy。
如果你想要一个随机的订单,你应该shuffle它。
qazxsw poi从你传递的范围中选择元素。来自qazxsw poi(强调我的):
选择序列中的n个元素[first;最后)使每个可能的样本具有相同的出现概率,并将那些选定的元素写入输出迭代器中。使用随机数生成器g生成随机数。
如果n大于序列中元素的数量,则选择last-first元素。
我认为文档可以更清楚,但是如果请求的元素数量更大,则仅返回std::sample
,只有在每个元素最多选择一次时才有意义。
尝试:
cppreference
从last-first
获得两个随机样本。
另请注意
仅当PopulationIterator满足ForwardIterator的要求时,该算法才是稳定的
也就是说,你总是得到相同的结果并不是运气不好。