1.知识点
(1)第一次题目集:简单类的创建,java.util.Scanner方法的运用,System.out.println、System.out.print、System.out.printf三种不同输出的区别,C语言中一些简单的if else条件判断语句,for循环,switch选择语句,加减乘除等运算。
(2)第二次题目集:类、数组的基本运用,分割字符串,数据类型之间的转换,删除重复数据的算法,无参构造和有参构造方法,度分秒的转换算法,多个类的设计。
(3)第三次题目集:多个类的设计,判断闰年,封装性面向对象的构造方法,计算成绩等算法,LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用,ChronoUnit类中DAYS、WEEKS、MONTHS的用法。
2.题量和难度
三次作业的题量逐渐减少,难度逐渐增加,通过具体的题目要求,逐步引导我们从面向过程的思维过渡到面向对象的思维。第一次题目集有八道题,基本上是一些简单的算法,有C语言的基础在我能轻松地写出。第二次题目集开始加难度了,涉及到一些Java的语句和算法,要求也加大,需要很多判定条件。第三次题目集虽然只有四道题,但是难度都比较大,每题都需要花费大量时间思考和修改,题目严格要求了我们创建类的格式,即包含若干属性和若干方法,而题目的具体要求则是在主类中通过调用具体类的具体方法来实现。
设计与分析
- 题目集2的7-1成绩计算-1-类、数组的基本运用
创建学生类,包含
属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)
方法:计算总分、计算平均分
输入5个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
浮点数保留小数的相关知识可参考:https://blog.csdn.net/huaishuming/article/details/17752365
注意:未用学生类对象封装数据的,本题计0分
输入格式:
5个学生信息,每个学生信息格式:
学号+英文空格+姓名+英文空格+语文成绩+英文空格+数学成绩+英文空格+物理成绩
例如:
22201311 张琳 80 80 80
22201312 黄昊 66 82 81
22201313 李少辰 77 76 80
22201314 袁婷 62 79 90
22201315 朱哲一 74 98 94
输出格式:
5个学生信息,每个学生信息格式:
学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分
例如:
22201311 张琳 240 80.00
22201312 黄昊 229 76.33
22201313 李少辰 233 77.67
22201314 袁婷 231 77.00
22201315 朱哲一 266 88.67
这道题主要考察用学生类对象封装数据,每个学生类中包含五个属性,分别是学号、姓名、语文成绩、数学成绩、英语成绩;包含两个方法,分别是计算总成绩 gettotal_sc()和计算平均分 getaverage_sc()。
本题需要用一个数组来存放五个学生的信息。输入部分采用了for循环逐步将五个学生的信息存入数组Main[]中。输出也是采用了for循环逐个显示结果。平均分结果要求精确到小数点后两位,我采用的是System.out.printf("%.2f",stu[i].getaverage_sc());限制。
类图如下:
源代码如下:
import java.util.Scanner;
public class Main {
String ID;
String name;
int Chinese_sc;
int Math_sc;
int English_sc;
//计算总成绩
public int gettotal_sc() {
return Chinese_sc + Math_sc + English_sc;
}
//计算平均分
public double getaverage_sc() {
return gettotal_sc() / 3.00;
}
public static void main(String[] args) {
//System.out.print("请分别输入五个学生的学号、姓名、各科成绩:");
Scanner input = new Scanner(System.in);
Main[] stu = new Main[5];
for (int i = 0; i < 5; i++) {
stu[i] = new Main();
stu[i]. ID = input.next();
stu[i]. name = input.next();
stu[i]. Chinese_sc = input.nextInt();
stu[i]. Math_sc = input.nextInt();
stu[i]. English_sc = input.nextInt();
//stu[i]=new student(ID, name, Chinese_sc, Math_sc, English_sc);Integer.parseInt(input.nextLine());
}
for (int i = 0; i < 5; i++) {
System.out.print(stu[i].ID+" ");
System.out.print(stu[i].name+" " );
System.out.print(stu[i].gettotal_sc()+" ");
System.out.printf("%.2f",stu[i].getaverage_sc());
System.out.println("");
}
}
}
- 题目集2的7-2成绩计算-2-关联类
创建成绩类,包含:
属性:平时成绩(int)、期末成绩(int)
方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)
创建学生类,包含:
属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)
方法:计算总分、计算平均分
输入3个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
浮点数保留小数的相关知识可参考:https://blog.csdn.net/huaishuming/article/details/17752365
注意:未用学生类对象封装数据的,本题计0分
输入格式:
依次输入3个学生的每门课成绩,每个学生成绩信息格式:
学号+英文空格+姓名+英文空格+课程名+英文空格+平时成绩+英文空格+期末成绩
注:3个学生的课程顺序可能会不一致
例如:
22201311 张琳 语文 70 80
22201311 张琳 数学 85 89
22201311 张琳 物理 75 83
22201312 黄昊 语文 66 78
22201312 黄昊 数学 76 82
22201312 黄昊 物理 83 82
22201313 李少辰 语文 86 76
22201313 李少辰 数学 78 76
22201313 李少辰 物理 87 76
输出格式:
3个学生信息,每个学生信息格式:
学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分
例如:
22201311 张琳 242 80.67
22201312 黄昊 234 78.00
22201313 李少辰 236 78.67
输入样例:
在这里给出一组输入。例如:
22201311 张琳 语文 70 80
22201311 张琳 数学 85 89
22201311 张琳 物理 75 83
22201312 黄昊 语文 66 78
22201312 黄昊 数学 76 82
22201312 黄昊 物理 83 82
22201313 李少辰 语文 86 76
22201313 李少辰 数学 78 76
22201313 李少辰 物理 87 76
输出样例:
在这里给出相应的输出。例如:
22201311 张琳 242 76.67 84.00 80.67
22201312 黄昊 234 75.00 80.67 78.00
22201313 李少辰 236 83.67 76.00 78.67
这道题创建了成绩类和学生类,首先是Score类,包含平时成绩和期末成绩属性,并提供计算总成绩的方法;接下来是Student类,包含学号、姓名和每门课程的成绩属性,并提供计算总分和平均分的方法。
在主函数中,首先创建一个空的students列表用于存储学生对象。
然后使用Scanner读取输入信息,并通过分割字符串获取学号、姓名、课程名、平时成绩和期末成绩。根据学号查找是否已存在该学生对象,若存在则直接添加该门课成绩,否则创建新的学生对象并加入到students列表中。
最后,遍历students列表,输出每个学生的总分和平均分,使用String.format("%.2f", student.getAverageScore())将平均分格式化为保留两位小数。
类图如下:
import java.util.Scanner;
class Score {
int dailyScore;
int finalScore;
public Score(int dailyScore, int finalScore) {
this.dailyScore = dailyScore;
this.finalScore = finalScore;
}
// 计算每科总成绩
public int getTotalScore() {
return (int) (dailyScore * 0.4 + finalScore * 0.6);
}
}
class Student {
String id;
String name;
Score chineseScore;
Score mathScore;
Score physicsScore;
public Student(String id, String name, Score chineseScore, Score mathScore, Score physicsScore) {
this.id = id;
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.physicsScore = physicsScore;
}
// 计算总分
public int sumTotalScore() {
int chineseTotal = chineseScore.getTotalScore();
int mathTotal = mathScore.getTotalScore();
int physicsTotal = physicsScore.getTotalScore();
return chineseTotal + mathTotal + physicsTotal;
}
// 计算平均分
public double sumAverageScore() {
int totalScore = sumTotalScore();
return totalScore / 3.0;
}
}
public class Main{
public static void main(String[] args) {
//输入
Scanner input = new Scanner(System.in);
Student []students = new Student[3];
for (int i = 0; i < 2; i++) {
String id = input.next();
String name = input.next();
int chineseDaily = input.nextInt();
int chineseFinal = input.nextInt();
int mathDaily = input.nextInt();
int mathFinal = input.nextInt();
int physicsDaily = input.nextInt();
int physicsFinal = input.nextInt();
Score chineseScore = new Score(chineseDaily, chineseFinal);
Score mathScore = new Score(mathDaily, mathFinal);
Score physicsScore = new Score(physicsDaily, physicsFinal);
students[i] = new Student(id, name, chineseScore, mathScore, physicsScore);
}
//输出
for (int j = 0; j < 2; j++) {
int totalScore = students[j].sumTotalScore();
double averageScore = students[j].sumAverageScore();
System.out.printf("%s %s %d %.2f\n", students[j].id, students[j].name, totalScore, averageScore);
}
}
}
- 题目集2的7-7菜单计价程序-1
某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9
设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)
不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格2。
如果计算出现小数,按四舍五入的规则进行处理。
本题需要创建多个类:
//菜品类
class Dish {
String name; // 菜品名称
int unit_price; // 单价
// 计算菜品价格的方法
public int getPrice(int quantity)
}
//菜谱类
class Menu {
Dish[] dishes; // 菜品数组,保存所有菜品信息
public Menu()
}
//点菜记录类
class Record {
Dish dish; // 菜品
int portion; // 份额
// 计价,计算本条记录的价格
public int getPrice()
}
//订单类
class Order {
Record[] records; // 保存订单上每一道的记录
// 添加一条菜品信息到订单中。
public Record addARecord(String dishName, int portion)
// 计算订单的总价
public int getTotalPrice()
}
首先需要读入每条点菜记录,并使用字符串的split()方法分割出菜名和份额。将菜名和基础价格的映射关系存储在一个数组中。
String[] arr = line.split(" ");
接着,根据菜名从arr[]中获取该菜品的基础价格,然后根据份额计算出不同份额菜的价格,并加入总价中。可以使用Java的Math.round()方法实现四舍五入的处理。最后输出总价即可。
类图如下:
- 题目集3的7-2 课程成绩统计程序-1
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。
- 1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。
课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
课程性质输入项:必修、选修
考核方式输入选项:考试、考察
课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
以上信息的相关约束:
1)平时成绩和期末成绩的权重默认为0.3、0.7
2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】
3)学号由8位数字组成
4)姓名不超过10个字符
5)课程名称不超过10个字符
6)不特别输入班级信息,班级号是学号的前6位。
2、输出:
输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。
为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。
1)学生课程总成绩平均分按学号由低到高排序输出
格式:学号+英文空格+姓名+英文空格+总成绩平均分
如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"
2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出
格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分
如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"
3)班级所有课程总成绩平均分按班级由低到高排序输出
格式:班级号+英文空格+总成绩平均分
如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"
异常情况:
1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"
2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"
以上两种情况如果同时出现,按第一种情况输出结果。
3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"
4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"
5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。
信息约束:
1)成绩平均分只取整数部分,小数部分丢弃
这道题内容量大,比较复杂,我没有完成。
- 踩坑心得
容易出现数据类型之间转换的错误,例如题目集3的7-4 判断两个日期的先后,计算间隔天数、周数。比如输入的是字符串string类型,输入两行,每行输入一个日期,日期格式如:2022-06-18。在计算两个日期相差的周数和天数时,需要进行类型转换,使用Integer.parseInt( )方法将string类型转变为int类型。
在输出部分,会出现与样例格式不符的情况,通常是因为没有精确到小数点后几位,例如题目集2的7-2成绩计算类,使用String.format("%.2f", student.getAverageScore())将平均分格式化为保留两位小数。
- 主要困难和改进建议
我认为第三次题目集布置的比较难,其中7-2 课程成绩统计程序这道题对于我来说并不容易,各个类之间的逻辑复杂,我很难完成。我觉得自己应当多多学习和探索,多加练习编写代码,锻炼自己的逻辑思维。对于建议,我希望老师上课时可以讲一些我们平时在PTA上面的习题,讲解一些内部逻辑。此外,建议老师多讲授一些思路和方法便于我们更快更好地理解题目。
- 总结
通过前三次PTA作业的练习,我认识到自己仍然存在很多不足。从第一次作业较为基础的知识点应用,到第二次作业更为复杂的算法设计,再到第三次作业规范的类的创建,三次作业逐步引导我从面向对象程序设计的思维过渡到面向对象的程序设计思维。目前,我认为自己在Java的学习中仍存在不足,对其具体的内部原理了解不够透彻,仍需要进一步学习和实践。除此之外,我对于多个类的程序设计仍比较陌生,需要更进一步的学习。