给定一个函数rand6()以相等的概率返回从1到6的随机数,请使用rand6()实现一个线性函数rand12(),该函数以相等的概率返回从1到12的随机数。解决方案应尽量减少对rand6()方法的调用。不允许使用任何其他库函数和浮点算法。
这个想法是使用表达式rand6()+(rand6()%2)* 6 。它以相等的概率返回从1到12的随机数。该表达式等效于–
// if rand6() is even
if (rand6() % 2)
return 6 + rand6();
else // if rand6() is odd
return rand6();
我们还可以使用以下任何一种以类似方式工作的表达式–
- rand6()+!(rand6()%2)* 6或
- rand6()+(rand6()&1)* 6或
- rand6()+!(rand6()&1)* 6
以下是上述想法的C++实现–
// C++ Program to print random numbers from 1 to 12
// with equal probability using a function that returns
// random numbers from 1 to 6 with equal probability
#include
using namespace std;
// Function that returns random numbers from 1 to 6
// with equal probability
int rand6()
{
// rand() will generate random numbers between 0 and
// RAND_MAX with equal probability
// rand() % 6 returns number from 0 to 5 equal probability
// (rand() % 6) + 1 returns number from 1 to 6 with
// equal probability
return (rand() % 6) + 1;
}
// The function uses rand6() to return random numbers
// from 1 to 12 with equal probability
int rand12()
{
return rand6() + (rand6() % 2) * 6;
}
// Driver code to test above functions
int main()
{
// Initialize random number generator
srand(time(NULL));
int N = 12;
int freq[N + 1] = { 0 };
// call rand12() multiple times and store its results
for (int i = 0; i < N * 100000; i++)
freq[rand12()]++;
// print frequency of numbers 1-12
for (int i = 1; i <= N; i++)
cout << freq[i] << " ";
return 0;
}
输出:
100237 100202 99678 99867 100253 99929 100287 100449 99827 99298 100019 99954
另一个解决方案–
int rand12()
{
return (rand6() * 2) - (rand6() & 1);
}
rand6()* 2将以相等的概率返回偶数2、4、6、8、10和12,而rand6()和1将基于rand6()分别为偶数或奇数返回0或1。因此,表达式(rand6()* 2)–(rand6()&1)将以相等的概率返回从1到12的随机数。
请注意,每次运行这些解决方案时,它们都会产生不同的结果。