初级--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,
思路:
- f1函数----实现1 ~5随机获取
- f2函数----等概率返回0和1
- f3函数----得到000 ~ 111 做到等概率 0 ~ 7等概率返回一个
- f4函数----0 ~ 6等概率返回一个
- 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]随机对数器的使用