初级--02---前缀和数组Math.random()对数器和随机行为

Posted 高高for 循环

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初级--02---前缀和数组Math.random()对数器和随机行为相关的知识,希望对你有一定的参考价值。


前缀和数组

1. 什么是前缀和

  • 前面的所有,再包括自己(数组 第 0 项 到 当前项 的 总和)

如果用一个数组 preSum 表示:

  • preSum[0]:数组A 第 0 项 到 第 0 项 的总和
  • preSum[1]:数组A 第 0 项 到 第 1 项 的总和
  • preSum[2]:数组A 第 0 项 到 第 2 项 的总和
  • preSum[3]:数组A 第 0 项 到 第 3 项 的总和
  • …… 于是有:
    preSum[i]=A[0]+A[1]+…+A[i]

数组某项,可以表示为相邻前缀和之差:

A[i]=preSum[i]−preSum[i−1]

代码实现

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];
        }

    }

随机函数 Math.random()

介绍:

Math.random()是令系统随机选取大于等于 0.0 且小于 1.0的伪随机 double

公式总结:

产生一个[0,1)之间的随机数。

Math.random():

返回大于等于0小于n之间的随机数

int num=(int)(Math.random()*n);

返回指定范围的随机数(m-n之间)的公式:

Math.random()*(n-m)+m; //包括m ,不包括n

或者

Math.random()*(n+1-m)+m //包括m ,也包括n

案例 1:

需求: 返回0-5之前的随机数

(int) (Math.random() * 6)

public class Test2 {
    public static void main(String[] args) {
        int testTimes = 10000000;


        int K = 6;
        int[] counts = new int[6];

        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] + " 次");
        }
    }
    

}

案例2: 我们需要取2~22之间的偶数

(int)2+(int)(Math.random()*(22-2));

public class Test03 {

    public static int GetevenNum(double num1,double num2){
        int s=(int)num1+(int)(Math.random()*(num2-num1));
        if(s%2==0){
            return s;
        } else{
            return s+1;
        }

    }
    public static void main(String[] args){
        System.out.println("任意一个num1_num2之间的偶数:"+GetevenNum(2,22));
    }
}

案例 3:

需求:

任意的x,x属于[0,1),[0,x)范围上的数出现概率由原来的x调整成x平方

Math.max(Math.random(), Math.random());

经典题---- 随机函数

题目1:

需求:

  • 随机机制,只能用f1,

思路:

  1. f1函数----实现1 ~5随机获取
  2. f2函数----等概率返回0和1
  3. f3函数----得到000 ~ 111 做到等概率 0 ~ 7等概率返回一个
  4. f4函数----0 ~ 6等概率返回一个
  5. g函数----实现1~7随机返回
	// 随机机制,只能用f1,
	public static int f1() {
		return (int) (Math.random() * 5) + 1;
	}
	// 等概率返回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;
	}

题目 2:

分析:

你只能知道,x会以固定概率返回0和1,但是x的内容,你看不到!

public static int x() {
	return Math.random() < 0.84 ? 0 : 1;
}

那么我们调用 2次会有4中情况 ,假设出现0的概率为p,那么出现1的概率就为(1-p)

  • 0,0 -----p * p
  • 0,1 -----p * (1-p)
  • 1,0 -----(1-p) * p
  • 1,1-----(1-p) * (1-p)

由此可知,出现(0,1) 和 (1,0)的概率 为一样

等概率返回0和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;
	}

对数器

用于校对数据正确与否的模拟器

验证选择排序

    public static void selectionSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            swap(arr, i, minIndex);
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

对数器


    // 返回一个数组arr,arr长度[0,maxLen-1],arr中的每个值[0,maxValue-1]
    public static int[] lenRandomValueRandom(int maxLen, int maxValue) {
        int len = (int) (Math.random() * maxLen);
        int[] ans = new int[len];
        for (int i = 0; i < len; i++) {
            ans[i] = (int) (Math.random() * maxValue);
        }
        return ans;
    }

    public static int[] copyArray(int[] arr) {
        return  Arrays.copyOf(arr, arr.length);
    }

    // arr1和arr2一定等长
    public static boolean isSorted(int[] arr) {
        if (arr.length < 2) {
            return true;
        }
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (max > arr[i]) {
                return false;
            }
            max = Math.max(max, arr[i]);
        }
        return true;
    }

    public static void main(String[] args) {
        int maxLen = 5;
        int maxValue = 1000;
        int testTime = 2;
        for (int i = 0; i < testTime; i++) {
            int[] arr1 = lenRandomValueRandom(maxLen, maxValue);
            int[] tmp = copyArray(arr1);

            selectionSort(arr1);
            if (!isSorted(arr1)) {
                for (int j = 0; j < tmp.length; j++) {
                    System.out.print(tmp[j] + " ");
                }
                System.out.println();
                System.out.println("选择排序错了!");
                break;
            }


            Arrays.stream(arr1).forEach((s)-> System.out.print(s+" "));
            System.out.println("排序正确");
        }

    }

结果:

  • 正确
  • 错误

以上是关于初级--02---前缀和数组Math.random()对数器和随机行为的主要内容,如果未能解决你的问题,请参考以下文章

Java算法 -- 选择排序冒泡排序插入排序前缀和数组Java中的Math.random()函数01不等概率随机到01等概率随机从[1,5]随机到[1,7]随机对数器的使用

Java算法 -- 选择排序冒泡排序插入排序前缀和数组Java中的Math.random()函数01不等概率随机到01等概率随机从[1,5]随机到[1,7]随机对数器的使用

Java算法 -- 选择排序冒泡排序插入排序前缀和数组Java中的Math.random()函数01不等概率随机到01等概率随机从[1,5]随机到[1,7]随机对数器的使用

JS:数组的 Math.random

Math类Random类与数组集合

JS:数组的 Math.random