第二节-数字随机性
作者:互联网
public class Demo2 { // 计算数据某一范围的数值的和 // 1 public static class RangeSum1 { private int[] arr; public RangeSum1(int[] array) { arr = array; } public int rangeSum(int L, int R) { int sum = 0; for (int i = L; i <= R; i++) { sum += arr[i]; } return sum; } } // 2 public static class RangeSum2 { private int[] preSum; public RangeSum2(int[] array) { int N = array.length; preSum = new int[N]; preSum[0] = array[0]; for (int i = 1; i < N; i++) { preSum[i] = preSum[i - 1] + array[i]; } } public int rangeSum(int L, int R) { return L == 0 ? preSum[R] : preSum[R] - preSum[L - 1]; } } // 此函数只能用,不能修改 // 等概率返回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) { System.out.println("测试开始"); // Math.random() -> double -> [0,1) // int testTimes = 10000000; int count = 0; for (int i = 0; i < testTimes; i++) { if (Math.random() < 0.75) { count++; } } System.out.println((double) count / (double) testTimes); // 结果接近设置的0.75,设置的是多少,结果就接近多少! System.out.println("========="); // [0,1) -> [0,8) count = 0; for (int i = 0; i < testTimes; i++) { if (Math.random() * 8 < 5) { count++; } } System.out.println((double) count / (double) testTimes); // 结果接近8分之5 System.out.println((double) 5 / (double) 8); // 打印8分之5的结果:0.625 int K = 9; // [0,K) -> [0,8] int[] counts = new int[9]; for (int i = 0; i < testTimes; i++) { int ans = (int) (Math.random() * K); // [0,K-1] counts[ans]++; } // 打印每个数打印的次数 最后结果:每个数出现的次数接近! for (int i = 0; i < K; i++) { System.out.println(i + "这个数,出现了 " + counts[i] + " 次"); } System.out.println("========="); count = 0; double x = 0.17; for (int i = 0; i < testTimes; i++) { // 调下面方法 if (xToXPower2() < x) { count++; } } System.out.println((double) count / (double) testTimes); // 0.3109616 System.out.println((double) 1 - Math.pow((double) 1 - x, 2)); // 0.31110000000000004 System.out.println("=========="); count = 0; for (int i = 0; i < testTimes; i++) { if (f2() == 0) { count++; } } System.out.println((double) count / (double) testTimes); // 0.4999636 System.out.println("=========="); 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] + " 次"); } } // 返回[0,1)的一个小数 // 任意的x,x属于[0,1),[0,x)范围上的数出现概率由原来的x调整成x平方 public static double xToXPower2() { return Math.min(Math.random(), Math.random()); } // lib里的,不能改! public static int f1() { return (int) (Math.random() * 5) + 1; } // 随机机制,只能用f1, // 等概率返回0和1 public static int f2() { int ans = 0; do { ans = f1(); } while (ans == 3); return ans < 3 ? 0 : 1; } // 得到000 ~ 111 做到等概率 0 ~ 7等概率返回一个 public static int f3() { return (f2() << 2) + (f2() << 1) + f2(); } // 0 ~ 6等概率返回一个 public static int f4() { int ans = 0; do { ans = f3(); } while (ans == 7); return ans; } public static int g() { return f4() + 1; } // 你只能知道,x会以固定概率返回0和1,但是x的内容,你看不到! public static int x() { return Math.random() < 0.84 ? 0 : 1; } // 等概率返回0和1 public static int y() { int ans = 0; do { ans = x(); } while (ans == x()); return ans; } }
标签:随机性,数字,int,double,System,++,println,第二节,out 来源: https://www.cnblogs.com/abiu/p/14362476.html