每次生成不同的随机数,而不是连续六次生成相同的随机数。
用例场景
我把“可预测性”的问题比作一袋六块纸,每个纸上写着一个从0到5的值。每当需要一个新的数值时,就会从袋子里抽出一张纸。如果袋子是空的,那么数字被放回袋子。
根据这个,我可以创建一个算法。
算法
一个包通常是一个集合。我选择了bool[](也称为布尔数组,位平面或位图)来扮演袋子的角色。
我选择bool[]的原因是,每一项的索引已经是每张纸的值。如果论文需要在它们上面写任何东西,那么我将使用Dictionary<string, bool>代替它。布尔值用于跟踪数字是否已经绘制。
一个名为RemainingNumberCount的计数器被初始化为5,当选择一个随机数时,计数器会向下计数。这样,我们就不必在每次想要画一个新数字时,都要计算还剩下多少张纸了。
为了选择下一个随机值,我使用for..循环来扫描索引包,并使用一个计数器来计数,当索引为false时,称为NumberOfMoves。
NumberOfMoves用于选择下一个可用号码。NumberOfMoves首先被设置为0到5之间的随机值,因为有0..我们可以通过袋子的5个可行步骤。在下一次迭代中,NumberOfMoves被设置为0到4之间的随机值,因为现在有0..我们可以用4步穿过袋子。在使用这些数字时,可用的数字会减少,因此我们使用rand() % (RemainingNumberCount + 1)来计算NumberOfMoves的下一个值。
当NumberOfMoves计数器为零时,for..循环应该如下所示:
将当前值设置为与..循环的索引。
将包中的所有数字设置为false。
停止for..循环。
Code
上述解决方案的代码如下:
(将以下三个块依次放入主.cpp文件中)
#include "stdafx.h"
#include <ctime>
#include <iostream>
#include <string>
class RandomBag {
public:
int Value = -1;
RandomBag() {
ResetBag();
}
void NextValue() {
int BagOfNumbersLength = sizeof(BagOfNumbers) / sizeof(*BagOfNumbers);
int NumberOfMoves = rand() % (RemainingNumberCount + 1);
for (int i = 0; i < BagOfNumbersLength; i++)
if (BagOfNumbers[i] == 0) {
NumberOfMoves--;
if (NumberOfMoves == -1)
{
Value = i;
BagOfNumbers[i] = 1;
break;
}
}
if (RemainingNumberCount == 0) {
RemainingNumberCount = 5;
ResetBag();
}
else
RemainingNumberCount--;
}
std::string ToString() {
return std::to_string(Value);
}
private:
bool BagOfNumbers[6];
int RemainingNumberCount;
int NumberOfMoves;
void ResetBag() {
RemainingNumberCount = 5;
NumberOfMoves = rand() % 6;
int BagOfNumbersLength = sizeof(BagOfNumbers) / sizeof(*BagOfNumbers);
for (int i = 0; i < BagOfNumbersLength; i++)
BagOfNumbers[i] = 0;
}
};
控制台类
我创建这个Console类是因为它可以很容易地重定向输出。
下面的代码中…
Console::WriteLine("The next value is " + randomBag.ToString());
...可以用……
std::cout << "The next value is " + randomBag.ToString() << std::endl;
...然后这个Console类可以根据需要删除。
class Console {
public:
static void WriteLine(std::string s) {
std::cout << s << std::endl;
}
};
主要方法
用法示例如下:
int main() {
srand((unsigned)time(0)); // Initialise random seed based on current time
RandomBag randomBag;
Console::WriteLine("First set of six...\n");
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
Console::WriteLine("\nSecond set of six...\n");
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
Console::WriteLine("\nThird set of six...\n");
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
Console::WriteLine("\nProcess complete.\n");
system("pause");
}
示例输出
当我运行程序时,我得到以下输出:
First set of six...
The next value is 2
The next value is 3
The next value is 4
The next value is 5
The next value is 0
The next value is 1
Second set of six...
The next value is 3
The next value is 4
The next value is 2
The next value is 0
The next value is 1
The next value is 5
Third set of six...
The next value is 4
The next value is 5
The next value is 2
The next value is 0
The next value is 3
The next value is 1
Process complete.
Press any key to continue . . .
关闭声明
该程序是使用Visual Studio 2017编写的,我选择使用. net 4.6.1使其成为Visual c++ Windows控制台应用程序项目。
我在这里没有做任何特别的事情,所以代码应该也适用于早期版本的Visual Studio。