题目
给定一个函数f1(),相当于这是lib库里的函数,等概率返回[3-19]。
利用这个给定的函数f1(),实现一个函数g(),等概率返回[17,56]
思路
要实现一个函数g()等概率返回[17,56],那么得先实现一个函数f4()等概率返回[0,39],再加17。
那么如何利用题目给定的函数f1()等概率返回[3-19],实现函数f4()等概率返回[0,39]呢。
我们可以先利用函数f1()实现一个函数f2(),等概率返回0和1.
再利用函数f2()实现一个函数f3(),等概率返回[0,39]. 运用二进制左移可以实现。
代码实现如下
public class Test {
public static void main(String[] args) {
int[] counts = new int[57];
int testTimes = 10000000;
//int count = 0;
for (int i = 0; i < testTimes; i++) {
int num = g();
counts[num]++;
}
for (int i = 17; i < 57; i++) {
System.out.println(i + "这个数,出现了 " + counts[i] + " 次");
}
}
//等概率返回[3-19]
public static int f1() {
return (int) (Math.random() * 17) + 3;
}
// 等概率返回0和1
public static int f2() {
int ans;
do {
ans = f1();
} while (ans == 11);
return ans < 11 ? 0 : 1;
}
/**
* 得到 000000~111111做到等概率 0~63
* 每次调用f2()函数得到0或1的概率都是1/2,
* 那么六次单独调用f2()函数(每次左移一位)得到00000~111111的概率为六个二分之一相乘,那么也是等概率的
* @return
*/
public static int f3() {
return (f2() << 5) + (f2() << 4) + (f2() << 3) + (f2() << 2) + (f2() << 1) + f2();
}
//得到 0~39等概率,f3()返回的值大于39我就重做
public static int f4() {
int ans = 0;
do {
ans = f3();
} while (ans > 39);
return ans;
}
//得到17~56等概率
public static int g() {
return f4() + 17;
}
}
测试结果如下
17这个数,出现了 250241 次
18这个数,出现了 250911 次
19这个数,出现了 249155 次
20这个数,出现了 249311 次
21这个数,出现了 250101 次
22这个数,出现了 249413 次
23这个数,出现了 249967 次
24这个数,出现了 250542 次
25这个数,出现了 250170 次
26这个数,出现了 250686 次
27这个数,出现了 250136 次
28这个数,出现了 249797 次
29这个数,出现了 250237 次
30这个数,出现了 250037 次
31这个数,出现了 249753 次
32这个数,出现了 249997 次
33这个数,出现了 250372 次
34这个数,出现了 250116 次
35这个数,出现了 250072 次
36这个数,出现了 249152 次
37这个数,出现了 250748 次
38这个数,出现了 249434 次
39这个数,出现了 249415 次
40这个数,出现了 249593 次
41这个数,出现了 249786 次
42这个数,出现了 249167 次
43这个数,出现了 250448 次
44这个数,出现了 250016 次
45这个数,出现了 249400 次
46这个数,出现了 250381 次
47这个数,出现了 249922 次
48这个数,出现了 250202 次
49这个数,出现了 250254 次
50这个数,出现了 249784 次
51这个数,出现了 250228 次
52这个数,出现了 249831 次
53这个数,出现了 250315 次
54这个数,出现了 250318 次
55这个数,出现了 250230 次
56这个数,出现了 250362 次