给定一个 0-4随机数生成器 如何生成0-6随机数并验证

4,468 阅读2分钟

人生就像爬坡, 要一步一步来。

最近群里经常有人讨论面试题,以后有机会给大家出一些有意思的题目,这些题难道不难,但是突然问到你,可能就会一时半会没有很好的思路。

明确任务

0-4随机数:0,1,2,3,4. 共计5个数字。

0-6随机数:0,1,2,3,4,5,6.共计7个数字。

如何用rand4() 能生成一个 rand6()呢?

思路

其实我们只需要生成一个比6大的数据范围,并且能确定每一个数字出现的概率都相同就可以了。

方法一 rand4() * rand4()

有人可能想rand4()*rand4() 在0-16范围,但是,实际上这16个数字里面并不是等概率的。

方法二 rand4() + rand4()

很显然,也不是等概率的,至少1就出现了2次,而0才出现1次。

方法三 n进制计算

我们把0-6进行排列,这样可以得到4*4=16个数字,而且每一个数字都是唯一的,最后一个44其实就是5进制的2位数。换算成10进制就是4*5 + 4 = 24, 就是0-24 共计25个数字。

在回到我们的问题,我们需要的是0-6的7个数字。现在有了25个数字:

7的1倍 = 7

7的2倍 = 14

7的3倍 = 21

7的4倍 = 28

所以我们需要21个数字的,当然7 和 14也是可以的,但是会有很多重复的计算。

所以21个数字就是0-20分成7等份。每份就是3个数字。

所以就有了下面的计算公式:

rand6() = {rand4() * 5 + rand4() }<=20?x/3:loop

代码实现

class Main{
    public static void main(String[] args) {
        int[] result = new int[7];
        for (int i = 0; i < 50000; i++) {
            int r = rand6();
            result[r]++;
        }
        for (int i = 0; i < result.length; i++) {
            System.out.println("num:" + i + " times: " + result[i]);
        }
    }

    public static int rand4() {
        //大于等于 0.0 且小于 1.0
        double rand = Math.random() * 5;
        return (int) rand;
    }

    // 0 -6 实际 7个数字
    public static int rand6() {
        int result = rand4() * 5 + rand4();
        do {
            result = rand4() * 5 + rand4();
        } while (result > 20);
        return result / 3;
    }
}

结果验证

我们随机进行了50000次验证,结果如下:

num:0 times: 7159
num:1 times: 7172
num:2 times: 7128
num:3 times: 7230
num:4 times: 7135
num:5 times: 7075
num:6 times: 7101

总结

现在你学会了由rand4()生成rand6()的方法,接下来你能分析下0-7生成0-9的过程吗?

希望可以帮助到你!