给定一个黑盒f(),这个黑盒f()可以等概率产生1-5,不可以修改f(),通过加工使其能够等概率生成1-7
步骤
给定得黑盒
public static int f(){
return (int) (Math.random()*5)+1;
}
将黑盒改造成0-1生成器
public static int f2(){
int ans=0;
do {
ans=f();
}while (ans==3);
return ans < 3 ? 0 : 1;
}
解释:定义一个变量ans,让他获取f()生成的值,如果ans=3将重新获取这个值,这样可以将黑盒产生的数分成两部分,1和2,是一部分,4和5是另一部分,再运用三目运算符,把小于3的部分都置为0,大于3的部分置为1
等概率生成0-7
public static int f3(){
int ans = (f2()<<2) + (f2()<<1) + f2();
return ans;
}
原理就是 用0-1生成器 生成三个数 将第一个左移两位 第二个左移一位 第三个不左移 就可以构成(0/1)*4+(0/1)*2+(0/1)都取0时最小为0 都取1时最大为7
将冗余的值重新生成需要的值(等概率生成0-6)
这个问题有两个方法 可以割7 也可以割0,以7为例
public static int f4(){
int ans=0;
do {
ans=f3();
}while (ans==7);
return ans;
}
原理是定义一个ans获取f3()获得的值,若获得的值是7将直接重新生成一个不为7的值
将生成的(0-6)加1
public static int g(){
return f4()+1;
}
全代码
public class A_B_C_D {
public static void main(String[] args) {
int count=0;
int testTimes=100000;
int[] counts = new int[8];
for (int i = 0; i < testTimes; i++) {
int num = g();
counts[num]++;
}
for (int i = 0; i < 8; i++) {
System.out.println(i+"这个数出现了"+counts[i]+"次");
}
}
}
public static int f(){
return (int) (Math.random()*5)+1;
}
//随机机制 只能用f()等概率返回0和1
//0-1发生器
public static int f2(){
int ans=0;
do {
ans=f();
}while (ans==3);
return ans < 3 ? 0 : 1;
}
//得到000-111等概率
public static int f3(){
int ans = (f2()<<2) + (f2()<<1) + f2();
return ans;
}
public static int f4(){
int ans=0;
do {
ans=f3();
}while (ans==7);
return ans;
}
public static int g(){
return f4()+1;
}
}
运行结果: