网上看到的一到算法题。
题目是给一个方法 foo(),能以各 50%的概率随机返回 0 或者 1。问题是基于 foo() 方法,实现一个 boo()方法,该方法能以各 10%的概率返回[0-9]中的一个数字。
foo() 方法返回 0 或 1,那么可以通过操作 foo() 来生成二进制数来实现。foo() 方法相当于抛一枚硬币,正反各 50%。抛4次硬币,共有16种组合。
分别是:
'0000', '0001', '0010', '0011',
'0100', '0101', '0110', '0111',
'1000', '1001', '1010', '1011',
'1100', '1101', '1110', '1111'
将得到的结果转为10进制数,然后判断是否小于10,小于则返回结果,大于则重新抛4次。这样就能已10%的概率返回[0-9]中的一个数字。
下面是Java的实现代码,随机返回 0 或者 1 是通过随机返回 0~99 的整数,然后取余。
1 import java.util.HashMap; 2 import java.util.Map; 3 import java.util.Random; 4 import java.util.Set; 5 6 public class Test { 7 8 /** 9 * 50%的概率随机返回 0 或者 1 10 */ 11 public int foo(){ 12 int seed = new Random().nextInt(100); 13 // System.out.println("seed=" + seed); 14 if(seed % 2 ==0){ 15 return 0; 16 } else { 17 return 1; 18 } 19 } 20 21 /** 22 * 以各 10%的概率返回[0-9]中的一个数字 23 */ 24 public int boo() { 25 String seed = String.valueOf(foo()) + String.valueOf(foo()) + String.valueOf(foo()) + String.valueOf(foo()); 26 // System.out.println(seed); 27 int reslut = Integer.valueOf(seed, 2); 28 while(reslut >= 10){ 29 reslut = boo(); 30 } 31 return reslut; 32 } 33 34 35 public static void main(String[] args) { 36 Test test = new Test(); 37 System.out.println(test.boo()); 38 39 //统计每个数字出现概率 40 Map<Integer, Double> countMap = new HashMap<Integer, Double>(); 41 int count = 1000000; 42 for (int i = 0; i < count; i++) { 43 int num = test.boo(); 44 if(countMap.get(num) == null){ 45 countMap.put(num, (double) 1); 46 } else { 47 countMap.put(num, countMap.get(num) + 1); 48 } 49 } 50 51 52 Set<Integer> keySet = countMap.keySet(); 53 for (Integer num : keySet) { 54 double ratio = countMap.get(num) / count; 55 double percent = ratio * 100; 56 System.out.println(num + "出现概率:" + percent + "%"); 57 } 58 } 59 }
结果
3
0出现概率:9.9815%
1出现概率:9.991999999999999%
2出现概率:10.0369%
3出现概率:10.005500000000001%
4出现概率:10.0336%
5出现概率:10.0071%
6出现概率:9.9441%
7出现概率:9.959800000000001%
8出现概率:9.989099999999999%
9出现概率:10.0504%
可以看出每个数字出现的概率基本都接近10%。
原文链接: