有没有一种更快的方法来从特定的数字池中获取随机数

时间:2019-07-26 05:29:12

标签: c++ random srand

我正在寻找一种更快的方法,该方法允许我从存储在数组中的某个数字池中获取随机数。

我将需要多次使用该方法,而当前方法正在极大地降低代码的速度。

#include <cstdlib>
#include <ctime>

int main()
{      
    const int size = 8;
    int numberArray[size] = { 0, 0, 3, 4, 0, 6, 7, 0 };
    srand(time(0));

    int rndIndex;
    int rndNumber;
    do 
    {
        rndIndex = rand() % size;
        rndNumber = numberArray[rndIndex];
    } while (rndNumber <= 0);
}

我喜欢从数组中获取随机数,除了随机数小于0

2 个答案:

答案 0 :(得分:1)

如果我的理解正确,那么您想从numberArray中重复选择一个非零数字,但是每次选择后数组中的数字都会发生变化(因为骑士使用不同的移动选项移动到另一个正方形) 。但是您当前的解决方案随着骑士的发展而变得越来越慢,因为move数组中的零越来越多,这使得您必须循环更多次才能选择非零值。

我知道,解决此问题的一种方法是首先计算数组中非零元素的数量。然后根据该数字进行随机选择(n),最后选择数组中的第n个非零数字。快速代码展示了这里的想法:

const int size = 8;
int numberArray[size] = { 0, 0, 3, 4, 0, 6, 7, 0 };
srand(time(0));

int numNonZero = 0;
for (int i = 0; i < size;++i) {
    if (numberArray[i] > 0)
        ++numNonZero;
}

int selectionNum;
int rndNumber;

selectionNum = rand() % numNonZero;

for (int i = 0; true; ++i) {
    rndNumber = numberArray[i];
    if (rndNumber > 0 && selectionNum-- == 0)
        break;
}

这可以交换随机数的循环,每个循环有一个rand()抽奖,最多可以有两个循环,每个循环最多包含8个元素和一个rand()抽奖。

顺便说一句!

由于我已经输入了这个内容,所以我只想提一下rand() % X是一种生成随机数(从0到X-1)的过时方法,而STL如今有一种更好的方法

更好的方法是执行以下操作:

const int size = 8;
int numberArray[size] = { 0, 0, 3, 4, 0, 6, 7, 0 };
std::random_device rd;
std::mt19937 mt(rd());  // initialize the random generator

int numNonZero = 0;
for (int i = 0; i < size;++i) {
    if (numberArray[i] > 0)
        ++numNonZero;
}

int selectionNum;
int rndNumber;

std::uniform_int_distribution<int> distribution(0, numNonZero - 1); // Set the distribution: 0 to numNonZero-1, both inclusive
selectionNum = distribution(mt);  // Generate random number in the selected range

for (int i = 0; true; ++i) {
    rndNumber = numberArray[i];
    if (rndNumber > 0 && selectionNum-- == 0)
        break;
}

您可以在http://www.cplusplus.com/reference/random/或此处Generate random numbers using C++11 random library

处阅读更多内容

答案 1 :(得分:0)

在数组中仅添加一次元素/数字。 您可以通过使用另一个计数器数组来跟踪该数组是否先前包含数字,如果之前包含数字,则不要包含它。现在,如果随机索引指向零值,则只需增加指针即可。