《算法第四版》课后练习题1.1.35答案
---恢复内容开始---
### 习题:1.1.35 ###### 以下代码能够计算每种两个骰子之和的准确概率分布: ```java int SIDES = 6; double[] dist = new double[2 * SIDES + 1]; for (int i = 1; i <= SIDES; i++) for (int j = 1; j <= SIDES; j++) dist[i + j] += 1.0;for (int k = 2; k <= 2 * SIDES; k++)
dist[k] /= 36.0;
###### dist[i] 的值就是两个骰子之和为i的概率。用实验模拟N次掷骰子,并在计算两个1到 6之间的随机整数之和时记录每个值的出现频率以验证它们的概率。N要多大才能够保证你的经验数据和准确数据的吻合程度达到小数点后三位?
一、实验思路分析:
1.计算掷两枚骰子所得点数之和的准确概率;
2.计算模拟掷N次所得两枚骰子点数之和的经验概率;
3.当经验概率与准确概率吻合到小数点后三位时输出数据。
<br>
<br/>
二、实验解释:
+ 关于存放概率的数组长度,骰子有六面,掷两枚可以依次掷出总和为2,3,4,5,6,7,8,9,10,11,12等一共11种结果,数组下标从0 开始标记,所以数组的长度在声明时需要声明成11+2 = 6*2+1 =SIDES*2+1一共13的长度;
+ 换个更简单的思路可以这么想,物理情况下总和最低是1+1=2,最高是6+6=12,存放12本质上是数据的第13个数据,因此声明长度为13的数组; 不用考虑具体的某一种情况的总和,因为i+j总和可以出现的情况是有穷的
+ 既然和的情况是有穷的,那么移植到模拟实验的部分,每次随机出来的两个数字m n,也就可以使用m+n将得到的和次数填充到数组里;
+ 反复对比,N*=2直到全部情况数据经验概率与准确概率吻合到小数点后三位时输出,其中p是用来控制循环的变量,当两种概率的吻合度并没有达到小数点后三位时,p始终置为0保证循环继续使N增大,N增大物理意义上就使得模拟掷骰子的次数上升了;直到全部情况的吻合度达到要求,跳出循环。
<br>
<br/>
三、实验代码:
```java
package Chapter1_1;
import java.util.Arrays;
import java.util.Scanner;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdRandom;
public class Ex35 {
//准确数据的概率
public static double[] dice() {
int SIDES=6;
double[] dist=new double[2*SIDES+1];
for(int i=1;i<=SIDES;i++) {
for(int j=1;j<=SIDES;j++) {
dist[i+j]+=1;
}
}
for(int k=2;k<=2*SIDES;k++) {
dist[k]/=36.0;
}
return dist;
}
//计算模拟掷N次所得两枚骰子点数之和的经验概率
public static double[] testDice(double N){
int SIDES = 6;
double[] a = new double[2*SIDES+1];
double t = N;
while(N>0){
int m = 1+(StdRandom.uniform(6));
int n = 1+(StdRandom.uniform(6));
a[m+n] += 1.0;
N--;
}
for(int i=2;i<=SIDES*2;i++){
a[i] /= t;
}
return a;
}
public static void main(String[] args) {
int SIDES=6;
double N=64;
boolean flag=true;
double[] b=dice();
System.out.println("准确数据的概率");
for(int i=0;i<b.length;i++) {
System.out.println(b[i]);
}
System.out.println();
double[] c=new double[2*SIDES+1];
int p=0;
while(flag) {
//p=1;
flag=false;
c=testDice(N);
for(int i=2;i<=2*SIDES;i++) {
if(Math.abs(b[i]-c[i])>0.0001) {
flag=true;
//p=0;
//flag=false;
// System.out.println("不符合题意要求,请重新输入一个更大的N值!");
break;
}
}
N*=2;
}
System.out.println("两骰和"+" "+"准确数据"+" "+"实验数据"+"所求N的值为:"+N);
for(int i=0;i<=2*SIDES;i++) {
System.out.println(i+" "+b[i]+" "+c[i]);
}
}
}
四、实验结果截图:
-
结果1:
-
结果2:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 一个费力不讨好的项目,让我损失了近一半的绩效!