package class025; public class Code02_RandToRand { // 此函数只能用,不能修改 // 等概率返回1~5 public static int f() { return (int) (Math.random() * 5) + 1; } // 等概率得到0和1 public static int a() { int ans = 0; do { ans = f(); } while (ans == 3); return ans < 3 ? 0 : 1; } // 等概率返回0~6 public static int b() { int ans = 0; do { ans = (a() << 2) + (a() << 1) + a(); } while (ans == 7); return ans; } // 等概率返回1~7 public static int c() { return b() + 1; } // 这个结构是唯一的随机机制 // 你只能初始化并使用,不可修改 public static class RandomBox { private final int min; private final int max; // 初始化时请一定不要让mi==ma public RandomBox(int mi, int ma) { min = mi; max = ma; } // 13 ~ 17 // 13 + [0,4] public int random() { return min + (int) (Math.random() * (max - min + 1)); } public int min() { return min; } public int max() { return max; } } // 利用条件RandomBox,如何等概率返回0和1 public static int rand01(RandomBox randomBox) { int min = randomBox.min(); int max = randomBox.max(); // min ~ max int size = max - min + 1; // size是不是奇数,odd 奇数 boolean odd = (size & 1) != 0; int mid = size / 2; int ans = 0; do { ans = randomBox.random() - min; } while (odd && ans == mid); return ans < mid ? 0 : 1; } // 给你一个RandomBox,这是唯一能借助的随机机制 // 等概率返回from~to范围上任何一个数 // 要求from<=to public static int random(RandomBox randomBox, int from, int to) { if (from == to) { return from; } // 3 ~ 9 // 0 ~ 6 // 0 ~ range int range = to - from; int num = 1; // 求0~range需要几个2进制位 while ((1 << num) - 1 < range) { num++; } // 我们一共需要num位 // 最终的累加和,首先+0位上是1还是0,1位上是1还是0,2位上是1还是0... int ans = 0; do { ans = 0; for (int i = 0; i < num; i++) { ans |= (rand01(randomBox) << i); } } while (ans > range); return ans + from; } public static void main(String[] args) { int[] count = new int[8]; // 0 1 2 .. 7 int testTime = 10000000; for (int i = 0; i < testTime; i++) { int ans = c(); count[ans]++; } for (int i = 0; i < 8; i++) { System.out.println(i + " : " + count[i]); } // RandomBox randomBox = new RandomBox(3, 9); // int from = 17; // int to = 29; // int[] ans = new int[to + 1]; // int testTime1 = 1000000; // for (int i = 0; i < testTime1; i++) { // ans[random(randomBox, from, to)]++; // } // for (int i = 0; i < ans.length; i++) { // System.out.println(ans[i]); // } // System.out.println("=========="); } }