给定一组整数:
std::set<int> itemInTest;
这个集合中有大约4000个整数,我想循环100次,每次它可以从集合中随机选择100个不同的元素。 此外,所有整数都是正数。
如何每次随机选择其中一个?我知道stackoverflow中有很多答案,但有些太复杂了,有些并不是那么随意。
答案 0 :(得分:8)
首先,将您的项目放入向量中,因为您需要多次随机访问它们:
vector<int> items(itemInTest.begin(), itemInTest.end());
然后,如果你需要100件物品并且不想两次选择同一件物品,那么你可以随便洗掉整件物品:
std::random_device rd;
std::mt19937 gr(rd());
shuffle(items.begin(), items.end(), gr);
现在只需要前100个元素。如果你想再次将它们放在一个集合中:
set<int> result(items.begin(), items.begin() + 100);
或者你可以使用你喜欢的任何输出容器类型 - 包括vector。
您可以再次执行random_shuffle
步骤,直到完成100次整体迭代。
如果您没有C ++ 11,则可以使用std::random_shuffle()
代替std::shuffle()
,并注意可以降低随机性的质量。那么你不需要std::mt19937
,只需:
random_shuffle(items.begin(), items.end());
答案 1 :(得分:1)
您可以使用Fisher–Yates shuffle:
类似的东西:
// Fisher–Yates_shuffle
std::vector<int> FisherYatesShuffle(std::size_t size, std::size_t max_size, std::mt19937& gen)
{
assert(size < max_size);
std::vector<int> b(size);
for(std::size_t i = 0; i != max_size; ++i) {
std::uniform_int_distribution<> dis(0, i);
std::size_t j = dis(gen);
if(j < b.size()) {
if(i < j) {
b[i] = b[j];
}
b[j] = i;
}
}
return b;
}
然后从索引中获取您的集合中的值(应将其转换为vector
以进行随机访问)。