之前看到一个算法题“用已有的rank7()函数生成rank10()函数”,看到了各种思路,不过看到一个可以用rankn()函数生成任意rankm()的通用方法比较有意思,就实现了一下记了下来。
该思路就是,首先用已有的rank7()生成随机数1-7,然后如果生成了1-3就返回0,生成了4-6就返回1,生成了7就重新生成。这样就把生成7个随机数变成等概率生成0或1。
然后用0和1生成一个4位的二进制数(因为 < 10 < ),因为每一位出现0和1的概率是相同的,所以从0000到1111这16个数字的概率也是相同的,然后用0000~1001这10个数分别对应1-10即可,如果生成了其他数就递归调用。
看代码:
import java.util.Random;
class Solution{
//循环四轮生成0000-1111二进制数并转换成1-10输出
public static int rand10() {
int a = 0;
for(int i = 0;i < 4;i++){
a *= 2;
a += rand2();
}
return a>9? rand10() : a+1;
}
//将7个随机数变成等概率生成0/1
public static int rand2(){
int a = rand7();
return a == 7? rand2() : a/4;
}
//用自带的rand7生成1-7随机数
public static int rand7(){
Random r = new Random();
return r.nextInt(7) + 1;
}
public static void main(String args[])
{
int array[] = new int[10];//用数组统计1-10的数量
for(int i = 0;i < 10;i++){
array[i] = 0;
}
//生成1000000个数,统计数量
for(int i = 0;i < 1000000;i++){
array[rand10() - 1] += 1;
}
for(int i = 0;i < 10;i++){
System.out.println((i+1) + "的数量:" + array[i]);
}
}
}
代码运行了3次,可以看到每次运行后生成10个数的数量差不多在10万左右
1的数量:99878 2的数量:100396 3的数量:99849 4的数量:100147 5的数量:100456 6的数量:99673 7的数量:99534 8的数量:100120 9的数量:99665 10的数量:100282 -------------------------------- 1的数量:99517 2的数量:99800 3的数量:100175 4的数量:100146 5的数量:99990 6的数量:99844 7的数量:100204 8的数量:100163 9的数量:100214 10的数量:99947 --------------------------------- 1的数量:100387 2的数量:99460 3的数量:99874 4的数量:100296 5的数量:100181 6的数量:100154 7的数量:99717 8的数量:99685 9的数量:100206 10的数量:100040



