今天是学习的第二天,额,效率有点低。
针对昨天的问题,百度了一下以及看了会源码(源码看得似懂非懂)还没找到答案...先搁置在这吧,
题.1.1.31
自己写的代码如下:
public static void randomConnection(double x, double y, double r, int N, double p) {
//draw circle
StdDraw.setXscale(0, 2*x);
StdDraw.setYscale(0, 2*y);
StdDraw.setPenColor(Color.RED);
StdDraw.setPenRadius(0.005);
StdDraw.circle(x, y, r);
//draw point
StdDraw.setPenColor(Color.BLACK);
StdDraw.setPenRadius(0.05);
double[][] points = new double[N][2];
if (N == 1)
StdDraw.point(x + r, y);
for (int i = 0; i < N; i++) {
double x1 = x + r*Math.cos(2*Math.PI*(i)/N);
double y1 = y + r*Math.sin(2*Math.PI*(i)/N);
StdDraw.point(x1, y1);
points[i][0] = x1;
points[i][1] = y1;
}
//将每对点按照概率p连接起来
StdDraw.setPenColor(Color.GRAY);
StdDraw.setPenRadius(0.003);
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < points.length; j++) {
if(true == StdRandom.bernoulli(p)) {
StdDraw.line(points[i][0], points[i][1], points[j][0], points[j][1]);
}
}
}
}
//------------------------------------
//这里插入一段参考答案
/**
* 画圆
* @param x 圆心x坐标
* @param y 圆心y坐标
* @param r 半径r
*/
private static void drawCircle(double x, double y, double r) {
StdDraw.setXscale(0, 2 * x);
StdDraw.setYscale(0, 2 * y);
StdDraw.setPenRadius(0.003);
StdDraw.setPenColor(StdDraw.BOOK_LIGHT_BLUE);
StdDraw.circle(x, y, r);
}
/**
* 在圆上描点
* @param x0 圆心x坐标
* @param y0 圆心y坐标
* @param r 半径r
* @param N N个点
*/
private static double[][] drawPoints(double x0, double y0, double r, int N) {
double[][] points = new double[N][2];
StdDraw.setPenRadius(0.005);
StdDraw.setPenColor(StdDraw.BOOK_RED);
for(int idx = 0; idx < N; ++idx) {
double x = x0 + r * Math.cos(2 * Math.PI * idx / N);
double y = y0 + r * Math.sin(2 * Math.PI * idx / N);
StdDraw.point(x, y);
points[idx][0] = x;
points[idx][1] = y;
}
return points;
}
/**
* 以概率p随机连接顶点集points中的点
* @param points 点集
* @param p 概率p
*/
private static void randomLinkPoints(double[][] points, double p) {
StdDraw.setPenRadius(0.002);
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
int length = points.length;
for(int i -= 0; i < length; ++i)
for(int j = 0; j < length; ++j)
if(true == StdRandom.bernoulli(p))
StdDraw.line(points[i][0], points[i][1], points[j][0], points[j][1]); // 应该再建立一个包含x坐标和y坐标的数据结构
}
/**
* 在圆上画N个点然后每两点间以概率p连接
* @param N N个点
* @param p 概率p
*/
private static void randomLink(int N, double p) {
double x = 10.0;
double y = 10.0;
double r = 9.0;
drawCircle(x, y, r);
double[][] points = drawPoints(x, y, r, N);
randomLinkPoints(points, p);
}
public static void main(String[] args) {
randomLink(20, 0.2);
}
额,大概花了一小时,写得太低效,刚开始学嘛
对比了一下自己写的和参考答案写的,明显参考答案写得更加清晰简洁,逻辑清晰。分为了几个小方法来描述,思路顺畅;而自己之所以花了一个小时,问题就在于逻辑没理顺,好吧,下一个题再好好思考。
题1.1.35模拟掷骰子
* 1.1.35 模拟掷骰子
*/
public static void main(String[] args) {
System.out.println(judge());
}
//骰子之和为m的理论概率
public static double[] accuratePro() {
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;
return dist;
}
//计算两个1 到 6 之间的随机整数之和
public static int sum() {
return StdRandom.uniform(1, 7) + StdRandom.uniform(1, 7);
}
//次数为N的概率
public static double[] actualPro(int N) {
int SIDES = 6;
double[] dist = new double[2 * SIDES + 1];
for (int i = 0; i < N; i++) {
dist[sum()] += 1.0;
}
for (int k = 2; k <= 2*SIDES; k++)
dist[k] /= (double)N;
return dist;
}
//求N,保证经验数据和准确数据的吻合程度达到小数点后三位
public static int judge() {
double[] arr1 = accuratePro();
int N = 1;
while(true) {
double[] arr2 = actualPro(N);
for (int i = 0; i < arr2.length; i++) {
if((arr1[i] - arr2[i]) >= 0.0001) {
N *= 10;
break;
}
if(i == arr2.length-1)
return N;
}
}
}
看到这个题,我算是发现了,方法还是不要太多得好,特别是对于一些方法看到方法名也不清楚干什么的时候,看起来比较费劲。嗯,这段感觉比参考答案好一点点。。(难道是因为自己写的缘故?,hhh)
1.1.36
哇这个题,我写得程序逻辑有点复杂,主要是题目有点拗口,打印一个M×M 的表格,对于所有的列j,行i 表示的是i 在打乱后落到j 的位置的次数。数组中的所有元素的值都应该接近于N/M,真的是,。。好在写出来了,哈哈,并且还比较简单
public static void main(String[] args) {
shuffleTest(5, 50000);
}
//乱序检查
public static void shuffleTest(int M, int N) {
double[] arr = new double[M];
double[][] arr1 = new double[M][M]; //直接打印比较困难,考虑用二维数组
for (int i = 0; i < N; i++) {
for (int n = 0; n < M; n++)
arr[n] = n;
StdRandom.shuffle(arr); //打乱程序
//直接打印比较困难,考虑用二维数组
for (int j = 0; j < arr1.length; j++) {
arr1[j][(int)arr[j]] += 1; //这个就是对于所有的列j,行i 表示的是i 在打乱后落到j 的位置的次数
}
}
for (int i = 0; i < arr1.length ; i++) {
for (int j = 0; j < arr1[0].length ; j++) {
System.out.print(arr1[i][j] + " ");
}
System.out.println();
}
}
对于1.1.39题,怎么说呢,耗费时间特别长,并且感觉没啥简便方法(找出俩数组中值相等的个数)。
今天学习到这。明天的话看1.2,此外的话,注意打印乱码问题,提醒下自己。