📜  在一行中使用rand6()实现rand12()

📅  最后修改于: 2021-04-29 11:59:05             🧑  作者: Mango

给定一个函数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的随机数。

请注意,每次运行这些解决方案时,它们都会产生不同的结果。