三、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;
}
本文为日常学习笔记,仅供参考