如何从c ++中的一个集合中随机选择一个元素?

时间:2015-12-14 10:51:20

标签: c++

给定一组整数:

std::set<int> itemInTest; 

这个集合中有大约4000个整数,我想循环100次,每次它可以从集合中随机选择100个不同的元素。 此外,所有整数都是正数。

如何每次随机选择其中一个?我知道stackoverflow中有很多答案,但有些太复杂了,有些并不是那么随意。

2 个答案:

答案 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;
}

Live example

然后从索引中获取您的集合中的值(应将其转换为vector以进行随机访问)。

相关问题