题目
给定一个函数f, 可以1~5的数字等概率返回一个。 请加工出1~7的数字等概率
返回一个的函数g。
给定一个函数f, 可以a~b的数字等概率返回一个。 请加工出c~d的数字等概率
返回一个的函数g。
给定一个函数f, 以p概率返回0, 以1-p概率返回1。 请加工出等概率返回0和1的
函数g
实现
package com.jpg.coding;
public class Rand5ToRand7 {
//已知的等概率返回1-5的函数
public static int f() {
return (int)(Math.random() * 5) + 1;
}
//如何实现等概率返回1-7?
//首先实现等概率返回0和1
//利用f()等概率随机返回1-5,如果返回的是12,就当做返回了0,如果返回的是45就当做
//返回了1,如果是3就重新随机生成,这样保证了生成0和1是等概率的
public static int r01() {
int res = 0;
do {
res = f();
}while (res == 3);
return res < 3 ? 0 : 1;
}
/*
* 利用r01()来等概率的返回1-7
* 遇到这种问题,思路就是想法拼凑出二进制位
* 比如7可以用二进制位111来表示,然后利用r01()来生成每个位置的值
* 最后要求返回是1-7,我们现在可以做到等概率返回0-7,所以可以先求出
* 0-6,然后再加1,如何生成0-6呢?和上述的思路一样,我们默认如果生成7就
* 重新生成
*/
public static int g() {
int res = 0;
do {
res = (r01() << 2) + (r01() << 1) + r01();
} while (res == 7);
return res + 1;
}
/*
* 如果现在给我们一个返回13-21的等概率函数,要求我们做出返回30-59等概率返回的函数
* 首先利用13-21函数制造一个等概率返回0和1的函数,然后我们可以利用这个r01(),做出
* 0-29,注意,一定要从0开始求,然后求得的值加上30就ok了
* 29是包含在111111(32)之内的,所以可以当生成的值大于29就重新生成
*/
/*
* 给定一个函数f, 以p概率返回0, 以1-p概率返回1。 请加工出等概率返回0和1的函数k
* 让f函数调用两次,如果是1,1重新调用,如果是0,0重新调用,如果是0,1就认为是0返回
* 如果是1,0就认为是1返回
*/
}