Day 10 —— Task1
1. Background
今天是学习java的第十天,是对之前所学内容的一个综合性训练。
在今天的程序训练中,我们用到了一个新的库——Random,这个库的作用是用来生成随机数。除此之外,用到的东西都是前面9天所学的循环、选择、数组这些。
2. Description
2.1 Random
这是一个生成随机数的库。具体用法可看下文Code部分。
此处列出Random的函数接口
boolean nextBoolean() // 返回下一个“boolean类型”伪随机数。
void nextBytes(byte[] buf) // 生成随机字节并将其置于字节数组buf中。
double nextDouble() // 返回一个“[0.0, 1.0) 之间的double类型”的随机数。
float nextFloat() // 返回一个“[0.0, 1.0) 之间的float类型”的随机数。
int nextInt() // 返回下一个“int类型”随机数。
int nextInt(int n) // 返回一个“[0, n) 之间的int类型”的随机数。
long nextLong() // 返回下一个“long类型”随机数。
2.2 Program
今天的程序是设定一组随机数构成的数组,作为一些学生的成绩。然后在这些数据中进行筛选,找到成绩最好的学生和成绩最差的学生。在数据筛选的时候,去除有科目不及格的学生。
程序有四部分组成:第一部分:建立一个二维数组,作为存放的载体,再将其中的填满随机数。
第二部分:创建一个新的数组,存放学生成绩的总分。如果学生有成绩不合格,总分直接按0分算。
第三部分:找出最好的学生和最差的学生。注意,最好和最差的学生输出需要单独判断,不可if - else。当最好和最坏的学生是同一个人时,if - else将会导致后判断的那个找不到所求的学生。
第四部分:输出上面所得到的结果。注意,最好和最差的学生输出需要单独判断,不可if-else。当所有学生都不合格时
3. Code
package basic;
import java.util.Arrays;
import java.util.Random;
/**
* This is the tenth code.
*
* @author Leo liu lyx1443807042@163.com
*/
public class Day10 {
/**
*****************
* The entrance of the program.
*
* @param args Not used now.
*****************
*/
public static void main(String[] args) {
Task1();
} // Of main
/**
*****************
* Method unit test.
*****************
*/
public static void Task1() {
// step 1. Generate the data with n student and m courses.
int n = 10;
int m = 3;
int lowerBound = 50;
int upperBound = 70;
int threshold = 60;
Random tempRandomNumber = new Random();
int[][] data = new int[n][m];
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[0].length; j++) {
data[i][j] = lowerBound + tempRandomNumber.nextInt(upperBound - lowerBound);
} // Of for j
} // Of for i
System.out.println("The data is: \r\n" + Arrays.deepToString(data));
// Step 2. Compute the total score of each student.
int[] totalScore = new int[n];
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[0].length; j++) {
if (data[i][j] < threshold) {
totalScore[i] = 0;
break;
} // Of if
totalScore[i] += data[i][j];
} // Of for j
} // Of for i
System.out.println("The total score are: \r\n" + Arrays.toString(totalScore));
// Step 3. Find the best student and the worse student.
// Initialization
int tempBestIndex = -1;
int tempWorseIndex = -1;
int tempBestScore = lowerBound;
int tempWorseScore = m * upperBound + 1;
for (int i = 0; i < totalScore.length; i++) {
if (totalScore[i] == 0) {
continue;
} // Of if
if (tempBestScore < totalScore[i]) {
tempBestScore = totalScore[i];
tempBestIndex = i;
} // Of if
if (tempWorseScore > totalScore[i]) {
tempWorseScore = totalScore[i];
tempWorseIndex = i;
} // Of if
} // Of for i
// Step 4. Output the student number and score.
if (tempBestIndex == -1) {
System.out.println("Cannot find best student. All failed.");
} else {
System.out.println("The best student is NO." + tempBestIndex + " with scores: "
+ Arrays.toString(data[tempBestIndex]));
} // Of if
if (tempWorseIndex == -1) {
System.out.println("Cannot find worse student. All failed");
} else {
System.out.println("The worse student is NO." + tempWorseIndex + " with scores "
+ Arrays.toString(data[tempWorseIndex]));
} // Of if
} // Of Task1
}// Of Day10
运行结果:
4. Summarize
今天的练习在逻辑想通的情况下不算困难。在第程序的Step 3.那里的最好最差判定,第一次做的确会因为考虑不周而写错,但是在看完老师的提示之后,想到了这一层也是很简单就可以避免这个bug了。
另外需要注意的一点是,随机数的生成tempRandomNumber.nextInt(upper)
这个函数得出的随机数范围是0到upper的前开后闭区间,即——[0, upper)。最后的那个upper是取不到的
如果要得到前闭后闭的区间,我这边建议把函数里面的upper
的数值加一。这样就取得到了,然后又因为取的是整数,取值也不会溢出。
想到这里,取整数的闭区间我们就解决了。可是如果是要取小数的闭区间呢?直接用函数的话只能得到前开后闭的区间,小数也不能直接+1.对于这个问题,我特地取Google上搜了一下,也没有好用的结果。
我在这里给出我和朋友的思路哈:
先取整数的随机数,然后进行类型转换,把int
型转换成float
或者double
型,然后把得到数除10的n次方。