首页 > 解决方案 > 制作一个小于十的不同随机整数的列表

问题描述

我想生成一个小于 10 的随机整数列表,它们不一样(不同的整数),例如(0、3、1、5、8)。但是我写的代码有问题,前两个整数总是相同的。如果您的代码告诉我我的代码的错误或为我提供另一种方法来做到这一点,那就太好了。

vector<int> rand_list(10, 11); //there is ten integers of 11   
for (int i = 0; i < 5; i++) // here we make 5 different integers
{
    srand(time(NULL));
    int r = rand() % 10;
    int check = 0;
    for (check; check <= i; check++)
    {
       if (r == rand_list[check])
       {
         srand(time(NULL));
         r = rand() % 10;
         check = 0;//I think this line don't force the second loop for to start again.
       }
    }
    rand_list[i] = r;
}

在这里,我希望 rand_list 有 5 个不同的整数,其他项目必须是 11,但前两个整数总是相同的!

标签: c++random

解决方案


不要srand()多次调用。time()具有秒精度,因此srand()在同一秒内多次调用time()作为种子将导致rand()每次返回相同的数字,这不是您想要发生的。只调用srand()一次,例如在程序启动时。

更好的是,根本不要使用 C 运行时的随机数生成器。请改用标准 C++ 随机数生成器。

至于您的算法,一个更简单的解决方案是将连续数字 0-9 放入一个数组中,然后运行一个循环,在该数组中生成一个随机索引并删除该元素以放入您的向量中,重复直到所有数组元素用尽了,例如:

#include <algorithm>
#include <random>

std::random_device rd;
std::mt19937 gen(rd());

std::vector<int> rand_list(10);

int numbers[10];
std::generate_n(numbers, 10, [n = 0]() mutable { return n++; });
int avail = 10;

for (int i = 0; i < 10; i++) {
    std::uniform_int_distribution<> dis(0, avail-1);  
    int r = dis(gen);
    rand_list[i] = numbers[r];
    std::copy(&numbers[r+1], &numbers[avail], &numbers[r]);
    --avail;
}

现场演示

或者更简单,您可以改用标准std::shuffle()算法,例如:

#include <algorithm>
#include <random>

std::random_device rd;
std::mt19937 gen(rd());

std::vector<int> rand_list(10);
std::generate_n(rand_list.begin(), 10, [n = 0]() mutable { return n++; });
std::shuffle(rand_list.begin(), rand_list.end(), gen);

现场演示


推荐阅读