17.11 Implement a method rand7() given rand5(). That is, given a method that generates a random number between 0 and 4 (inclusive), write a method that generates a random number between 0 and 6 (inclusive).
這道題說給了我們一個rand5()函式,可以生成0到4之間的隨機數,讓我們寫一個函式rand7()可以生成0到6之間的隨機數,那麼我們寫出來的這個rand7()函式必須生成0到6之間每個數字的概率為1/7。那麼我們首先想能不能用(rand5()+rand5())%7來做,答案是不行的,我們來看一下rand5()+rand5()中每個數字出現的概率:
0 (1/25)
1 (2/25)
2 (3/25)
3 (4/25)
4 (5/25)
5 (4/25)
6 (3/25)
7 (2/25)
8 (1/25)
而我們需要的rand7()是要0到6中每個數的出現概率是1/7才行,所以我們必須生成一個區間,每個數字的出現概率是相同的。那麼我們可以用5*rand5()+rand5(),這生成了[0, 24]區間中的25個數字,每個數字的出現概率都是1/25,那麼我們只要當隨機生成的數字小於21,對7取餘返回即可:
解法一:
int rand7() { while (true) { int num = 5 * rand5() + rand5(); if (num < 21) { return num % 7; } } }
其實我們也可以用2*rand5()來生成等概率區間,就是稍微麻煩一些,因為rand5()*2等概率的生成0,2,4,6,8,所以我們需要構造一個等概率生成0,1,和rand5()*2相加就是等概率生成[0,9]區間的數,參見程式碼如下:
解法二:
int rand7() { while (true) { int r1 = rand5() * 2; int r2 = rand5(); if (r2 != 4) { int num = r1 + r2 % 2; if (num < 7) { return num; } } } }