数据结构与算法(二)Math.random使用

三、Math.random() 方法的使用

// Math.random() 产生的数是等概率的[0,1), 计算机中的数是有精度的
public static void probability(int k, int testTimes) {
        int[] counts = new int[k];
        for (int i = 0; i < testTimes; i++) {
            int ans = (int)(Math.random() * k);
            counts[ans]++;
        }
        for (int i = 0; i < k; i++) {
            System.out.println(i+"数出现了:"+counts[i]+"次");
        }
    }

Math.pow(x,n)的实现:

// Math.pow(x,n)的实现
    public static void myPowern(double x,int testTimes) {
        int count = 0;
        for (int i = 0; i < testTimes; i++) {
            if (xToXPowern() < x) {
                count++;
            }
        }
        System.out.println((double) count/ (double)testTimes);
    }
    public static double xToXPowern() {
        return Math.max(Math.random(),Math.random(),……);// n个Math.random()的最大值;
    }

若将xToXPowern() 方法中Math.max() 改为Math.min() 则该方法实现的为:

// 1-(1-x)^2
    public static double xToXPower2() {
        return Math.min(Math.random(),Math.random());
    }
        myPower2(x,testTimes);
        System.out.println((double)1-Math.pow((double)1-x,2));

练习:

利用f() 方法 等概率返回1 ~ 7:

	// 不能修改 1~5
    public static int f() {
        return (int)(Math.random()*5) + 1;
    }

解析:因原概率范围为1 ~ 5 为奇数,排除一个数(这里是3),计算其它数等概率划分得到 0 ,1 上的等概率,

— — — (每个‘’—‘’都是 二进制0 或1 )总共8个数需要求7个数,排除一个数(这里排除7);

	// 等概率得到 0 和 1;
    public static int f1() {
        int ans = 0;
        do {
            ans = f();
        } while(ans == 3);
        return ans < 3 ? 0 : 1;
    }
    //等概率返回 0 ~ 6;
    public static int f2() {
        int ans = 0;
        do {
            ans = (f1()<<2)+(f1()<<1) + f();
        }while(ans == 7);
        return ans;
    }

    // 等概率返回1 ~ 7;
    public static int f3() {
        return f2() + 1;
    }

不等概率实现等概率:

	// x会以固定概率返回0 和 1
    public static int x() {
        return Math.random()<0.81 ? 0 : 1;
    }
    // 等概率返回0 和 1
    public static int y() {
        int ans = 0;
        do {
            ans = x();
        }while(ans == x());
        return ans;
    }

*1)对于任意min ~ max数:*条件

// 等概率获得 min ~ max;
    public static class RandomBox {
        private final int min;
        private final int max;

        public RandomBox(int min, int max) {
            this.min = min;
            this.max = max;
        }
        public int random() {
            return min + (int) (Math.random()*(max - min + 1));
        }

        public int getMin() {
            return min;
        }

        public int getMax() {
            return max;
        }
    }

2)转换为0 ~ 1概率

public static int random01(RandomBox randomBox) {
        int min = randomBox.min;
        int max = randomBox.max;
        int size = max - min + 1;
        int mid = size>>1;
        int ans = 0;
        boolean odd = (size & 1) == 0;
        do {
            ans = randomBox.random();
        }while(odd && ans == max);// 最后只有两个值0 和 1 只需要做到均分就好(如果为奇数个就在多的一方去掉一个数) 
        return ans < min+mid ? 0 : 1;
    }

3)转换为from ~ to 上的等概率

 public static int random(RandomBox randomBox, int from, int to) {
        if (from == to) return from;
        // 3 ~ 9;
        // 0 ~ 6;
        //求0 ~ from-to上的等概率;
        int range = to - from;
        int num = 1;// 需要多少二进制位;
        while((1<<num)-1 < range) {
            num ++;
        }
        int ans = 0;
        do {
            ans = 0;
            for (int i = 0; i < num; i++) {
                ans |= (random01(randomBox)<<i);
            }
        } while(ans > range);
        return ans + from;
    }
使用Math.random写测试:
 public static int[] lenRandomValueRandom(int maxLen, int maxValue) {
        int len = (int)(Math.random() * maxLen);
        int[] arr = new int[len];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random() * maxValue);
        }
        return arr;
    }

    public static int[] copyarry(int[] arr) {
        int[] array = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            array[i] = arr[i];
        }
        return array;
    }
    public static void main(String[] args) {
        int maxLen = 10;
        int maxValue = 1000;
        int testTimes = 10;
        for (int i = 0; i < testTimes; i++) {
            int[] arr = lenRandomValueRandom(maxLen, maxValue);//准备测试数据
            int[] copyarry = copyarry(arr);
            insertSort(arr);// 处理方式
            if (!isSorted(arr)) {// 出错后的处理方式
                for (int i1 = 0; i1 < copyarry.length; i1++) {
                    System.out.print(arr[i1] +" ");
                }
                System.out.println();
                System.out.println("排序出错!");
                for (int i1 : arr) {
                    System.out.print(i1+" ");
                }
                System.out.println();
            }
        }

    }
	private static boolean isSorted(int[] arr) {
        if (arr.length < 2) return true;
        for (int i = 1; i < arr.length; i++) {
            if (arr[i-1]>arr[i]) return false;
        }
        return true;
    }

本文为日常学习笔记,仅供参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值