https://www.jianshu.com/p/6d9b3e8df760

思路:

1、random5 只生成1、2、3、4、5,每个字符概率相同,1、2、3、4的概率相同,生成5时抛弃并重新生成,即为random4

2、将random5扩大到randomN,N>7,即可实现random7

考虑以下公式:

5 * random5() - random5() + 1

被减数5*random5()会等概率生成510152025,与减数random5()互为独立事件,所以5 * random5() - random5()会等概率生成0~24+1后可等概率生成1~25,即得到random25

抛弃>7的数据可得到random7,然而重复次数太多。

抛弃22232425的结果得到random21并利用以下公式改造:

random21() % 7 + 1 

即为random7

完整代码:


    static int random5(){
        return (int)(Math.random() * 5 + 1);
    }

    static int random7(){
        int rnd = 0;
        do{
            rnd = 5 * random5() - random5() + 1;
        }while (rnd > 21);
        return rnd % 7 + 1;
    }

    public static void main(String[] args) {
        // 生成100万次统计概率
        Map<Integer, Integer> counter = new HashMap<>();
        for(int i = 0 ; i < 1000000 ; i ++){
            int rnd = random7();
            counter.putIfAbsent(rnd, 0);
            counter.put(rnd, counter.get(rnd) + 1);
        }
        for(Integer k : counter.keySet()){
            System.out.println(k + ":" + counter.get(k)/1000000d);
        }
    }

输出结果:

1:0.143201
2:0.14319
3:0.142439
4:0.142904
5:0.142342
6:0.142865
7:0.143059