已知函数 f() 等概率返回1到5,只使用 f() 函数实现等概率返回1到7。
思路:
(1)使用 f() 函数构造 f1() 函数,使 f1() 函数等概率返回0和1
(2)使用 f1() 函数构造 f2() 函数,使 f2() 函数等概率返回0和7
(3)使用 f2() 函数构造 f3() 函数,使 f3() 函数等概率返回1和7
原 f() 函数(不可更改):
/**
* 原始函数,等概率返回1到5 不能更改
*/
public static int f() {
return (int) (Math.random() * 5 + 1);
}
f1() 函数,等概率返回0和1:
/**
* 利用f()函数,等概率返回0和1
*
* @return 0或者1
*/
public static int f1() {
int ans;
do {
ans = f();
} while (ans == 3);
return ans < 3 ? 0 : 1;
}
f2() 函数,等概率返回0到7:
/**
* 利用f1()函数,等概率返回0到7
*
* @return 0到7
*/
public static int f2() {
return (f1() << 2) + (f1() << 1) + f1();
}
f3() 函数,等概率返回1到7:
/**
* 等概率返回1到7
*
* @return 1到7
*/
public static int f3() {
// 等概率返回0到6
int ans;
do {
ans = f2();
} while (ans == 7);
// 等概率返回1到7
return ans + 1;
}
验证:
public static void main(String[] args) {
int count = 100000;
Map<Integer, Integer> countMap = new HashMap<>(16);
for (int i = 0; i < count; i++) {
int ans = f3();
countMap.computeIfPresent(ans, (v1, v2) -> countMap.get(ans) + 1);
countMap.putIfAbsent(ans, 1);
}
countMap.forEach((k, v) -> System.out.println("k=" + k + ",出现了" + v + "次,概率 " + (double) v / count));
}
验证结果: