目录:
1、前言
2、设计与分析
3、踩坑心得
4、主要困难及改进建议
5、总结
1、前言
面向对象程序设计(Object-Oriented Programming,简称OOP)是一种编程范式,它以对象作为程序的基本单元,将数据和操作封装在一起。面向对象程序设计的基本概念包括类、对象、继承、多态等。
-
类(Class)是面向对象程序设计的基本构建块,它是一种抽象的数据类型,用于描述具有相同属性和行为的对象的集合。类定义了对象的属性(成员变量)和行为(方法)。
-
对象(Object)是类的实例化结果,它是具体的、有状态的实体。对象可以根据类的定义,拥有自己的属性值,并能执行类中定义的方法。
-
继承(Inheritance)是一种机制,允许在已有类的基础上创建新类,新类可以继承和扩展已有类的属性和方法。继承能够提供代码的重用性和层次化的组织结构。
-
多态(Polymorphism)是指同一类型的对象在不同的情况下可以表现出不同的行为。多态性可以通过继承和接口实现,使得程序可以根据上下文选择合适的方法。
面向对象程序设计的优点包括代码的可重用性、可扩展性、易维护性和模块化等。它提供了一种更加灵活和抽象的编程方式,使得程序的设计和实现更加清晰和可管理。在前三次的作业中我主要使用了创建类和对象的知识,并未涉及到继承和多态的有关知识的运用。
第一次作业主要是一些java基础语法的应用,较为简单的输入输出应用,if-else、switch、while语句等循环、选择语句的应用,第一次作业体量大,但是难度低,比较重视我们的基础训练;
第二次作业开始接触封装的思想,题目主要针对于类以及对象的创建和应用、java自带的API的熟悉、各种类的运用,题目量大,难度也提高了许多;
第三次作业题量减少许多,相对难度是三次作业中最大的,其中关于类的创建和运用对于现在的我来说略感复杂。
2、设计与分析
第一次作业:
总体分析:这次作业主要设计到java语言的简单输入输出、字符串匹配、循环、选择语句的运用,其中对类的应用并不复杂。
类图如下:
7-1 身体质量指数(BMI)测算---------使用了简单的scanner类输入,经过简单的选择语句,即可得出正确答案
7-2 长度质量计量单位换算-----------主要是精度之间的转换,针对基本语法的考察,也不难
7-3 NCHU_奇数求和---------掌握算法,经过简单if-else语句,即可累加得出答案
7-4 NCHU_房产税费计算---------这道题只需要注意单位转换,输入和输出一一对应,与上面的难度相当
7-5 游戏角色选择----------这道题需要用到switch选择语句,可以减少复杂度。
7-6 NCHU_学号识别-----------这道题需要用到string类的有关方法,如substring、equals等来匹配学号的对应位数字
7-8 NCHU_巴比伦法求平方根近似值------运用math类的abs方法求绝对值,即可求出
7-9 二进制数值提取-------这道题主要用到了string类的charAt来获取字符串的某一位字符,来匹配二进制的0、1,进而判断
7-7 判断三角形类型-----------题目如下:
输入三角形三条边,判断该三角形为什么类型的三角形。输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。输出格式:
(1)如果输入数据非法,则输出“Wrong Format”;
(2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”;
(3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”;
(3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”;
(5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”;
(6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”;
(7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。
在这道题的解题过程中,我遇到一个始终过不去的测试点,就是那个等腰直角三角形的判断,我的算法是既符合等腰三角形的两边相等,又符合a的平方+b的平方=c的平方,但是始终无法通过这个测试点,后来经过网络查询,我想到或许是因为电脑对于无理数的输出不够准确,于是我把其判断条件改成了a*a+b*b-c*c<0.0001,这样缩小了精度,但是可能更符合电脑的对于无理数的处理,再次尝试就通过了测试点。
第二次作业:
第二次针对类的创建和应用开始接触的更加深入,面向对象的封装思想也在逐渐被使用,主要是数组和类的应用。
7-1 成绩计算-1-类、数组的基本运用-------题目如下:
创建学生类,包含
属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)
方法:计算总分、计算平均分
输入5个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
分析:这道题目开始接触数据封装思想,需要用学生类来封装学生的对应信息。
7-2 成绩计算-2-关联类--------题目如下:
创建成绩类,包含:
属性:平时成绩(int)、期末成绩(int)
方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)
创建学生类,包含:
属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)
方法:计算总分、计算平均分
输入3个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
分析:这道题涉及两个类的创建和数据的封装,创建一个学生类、一个成绩类关联解题
这两道题目类图相同:
这两道题目对我而言难度不是很大,我写的代码行数也较短,在此不赘述其代码复杂度。
在第二次作业中值得一提的是题目是7-7 菜单计价程序-1------题目如下:
某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9
设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)
不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格2。
如果计算出现小数,按四舍五入的规则进行处理。
参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}
菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}
点菜记录类:保存订单上的一道菜品记录
Record {
Dish d;//菜品
int portion;//份额(1/2/3代表小/中/大份)
int getPrice()//计价,计算本条记录的价格
}
订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(String dishName,int portion)
//添加一条菜品信息到订单中。
}
输入格式:
每条点菜记录的格式:
菜名+空格(英文)+份额
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
最后一条记录以“end”结束。
输出格式:
订单上所有菜品的总价(整数数值),每份菜
如果订单中包含不能识别的菜名,则在总价之前输出“** does not exist”,**是不能识别的菜名
在这里附上我的代码:
class Dish {
String name;
int unit_price;
public Dish(String name, int unit_price) {
this.name = name;
this.unit_price = unit_price;
}
public int getPrice(int portion) {
double price;
if (portion == 1) {
price = unit_price;
} else if (portion == 2) {
price = unit_price * 1.5;
} else if (portion == 3) {
price = unit_price * 2;
} else {
throw new IllegalArgumentException("Invalid portion: " + portion);
}
return (int) Math.round(price);
}
}
class Menu {
Dish[] dishes;
public Menu(Dish[] dishes) {
this.dishes = dishes;
}
public Dish searchDish(String dishName) {
for (Dish dish : dishes) {
if (dish.name.equals(dishName)) {
return dish;
}
}
return null;
}
}
class Record {
Dish dish;
int portion;
public Record(Dish dish, int portion) {
this.dish = dish;
this.portion = portion;
}
public int getPrice() {
return dish.getPrice(portion);
}
}
class Order {
Record[] records;
int size;
public Order(int capacity) {
records = new Record[capacity];
size = 0;
}
public void addARecord(String dishName, int portion) {
Dish dish = MenuHolder.menu.searchDish(dishName);
if (dish != null) {
Record record = new Record(dish, portion);
records[size] = record;
size++;
} else {
System.out.println(dishName + " does not exist");
}
}
public int getTotalPrice() {
int totalPrice = 0;
for (int i = 0; i < size; i++) {
totalPrice += records[i].getPrice();
}
return totalPrice;
}
}
class MenuHolder {
static Menu menu;
static {
Dish[] dishes = new Dish[4];
dishes[0] = new Dish("西红柿炒蛋", 15);
dishes[1] = new Dish("清炒土豆丝", 12);
dishes[2] = new Dish("麻婆豆腐", 12);
dishes[3] = new Dish("油淋生菜", 9);
menu = new Menu(dishes);
}
}
public class Main {
public static void main(String[] args) {
Order order = new Order(10);
java.util.Scanner scanner = new java.util.Scanner(System.in);
while (true) {
String input = scanner.nextLine().trim();
if (input.equalsIgnoreCase("end")) {
break;
}
String[] parts = input.split(" ");
if (parts.length == 2) {
String dishName = parts[0];
int portion = Integer.parseInt(parts[1]);
order.addARecord(dishName, portion);
} else {
System.out.println(input);
}
}
System.out.println( order.getTotalPrice());
scanner.close();
}
}
用power designer生成类图如下:
用source monitor 分析代码结果如下:
分析:
1、在dish类中记录菜名、菜品的基础价格,以及通过用户输入份额来计算菜品价格的方法。
2、在menu类里面定义了dish类的一个菜品数组来记录该餐厅有的菜品。
3、在record类里面记录客人的记录情况,每输入一道菜品的名字和价格视为一次记录。
4、在order类里面,用来记录订单情况,定义了一个record类的数组,定义了添加记录的方法。
5、在MenuHolder类里面保存了现有的菜品及其基础价格。
这道题主要难在类的关联以及调用方法实现题目所需的功能,我在做的时候遇到了很多问题,例如对record类和order类的定义和使用方法不太清楚,故而在跟踪调试的时候产生了很多问题,有几个测试点的输出跟需求不符,在经过网络查询后,对order类的对象进行了改变,从而得出正确答案。
第三次作业:
这次作业主要着重于时间类、面向对象编程封装数据、string类、arraylist类的应用。
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)成绩平均分只取整数部分,小数部分丢弃
题目类图如下:
我的代码如下:
import java.text.Collator;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String information = input.nextLine();
ParseInput handle = new ParseInput();
while (!information.equals("end"))
{
handle.parseInput(information);
information = input.nextLine();
}
handle.showStudents();
handle.showCourses();
handle.showClasses();}
private static double calculateDuplication1(String input1, String input2) {
Set<Character> set1 = new HashSet<>();
Set<Character> set2 = new HashSet<>();
for (char c : input1.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
set1.add(c);
}
}
for (char c : input2.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
set2.add(c);
}
}
Set<Character> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
double duplication = (double) intersection.size() / set1.size() * 100;
return duplication;
}
private static double calculateDuplication2(String input1, String input2) {
Set<Character> set1 = new HashSet<>();
Set<Character> set2 = new HashSet<>();
for (char c : input1.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
set1.add(c);
}
}
for (char c : input2.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
set2.add(c);
}
}
Set<Character> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
double duplication = (double) intersection.size() / set1.size() * 100;
return duplication;
}
}
class ParseInput {
ArrayList<Student> listStudent = new ArrayList<>();
ArrayList<Course> listCourse = new ArrayList<>();
ArrayList<Class> listClass = new ArrayList<>();
ArrayList<ChooseCourse> listChooseCourse = new ArrayList<>();
public void parseInput(String str){
InputMatching mat=new InputMatching();
int flag=mat.matchingInput(str);
switch (flag){
case 0:System.out.println("wrong format");
break;
//课程信息
case 1:courseMessage(str);
break;
//成绩信息
case 2:gradeMessage(str);
break;
}
}
private static String readInput(Scanner scanner) {
StringBuilder sb = new StringBuilder();
String line;
while (!(line = scanner.nextLine()).equals("end")) {
sb.append(line);
sb.append(System.lineSeparator());
}
return sb.toString();
}
private static double calculateDuplication(String input1, String input2) {
Set<Character> set1 = new HashSet<>();
Set<Character> set2 = new HashSet<>();
for (char c : input1.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
set1.add(c);
}
}
for (char c : input2.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
set2.add(c);
}
}
Set<Character> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
double duplication = (double) intersection.size() / set1.size() * 100;
return duplication;
}
public void courseMessage(String str) {
String letters[] = str.split(" ");
String courseName = letters[0];
String type = letters[1];
String testType = letters[2];
Course course = new Course(courseName, type, testType);
if (checkCourse(course)) {
if (searchCourse(courseName) == null)
listCourse.add(course);
}
}
public void gradeMessage(String str) {
String letters[] = str.split(" ");
String stuId = letters[0];
String classID = letters[0].substring(0, 6);
String name = letters[1];
String courseName = letters[2];
if (searchClass(classID) == null) {
Class cla = new Class(classID);
listClass.add(cla);
}
Student stu = new Student(classID, stuId, name);
if (!searchStudent(stuId))
listStudent.add(stu);//将学生加入列表中
//课程是否存在
if (searchCourse(courseName) == null) {
System.out.println(courseName + " " + "does not exist");
}
//当课程存在时
else if (searchCourse(courseName) != null) {
Course course = searchCourse(courseName);
//考察
if (letters.length == 4 && course.testType.equals("考察")) {
int finalGrade = Integer.parseInt(letters[3]);
AssessGrade assessGrade = new AssessGrade(finalGrade);
ChooseCourse chooseCourse = new ChooseCourse(course, stu, assessGrade);
if (!searchChooseCourse(name, courseName))
listChooseCourse.add(chooseCourse);
}
//考试
else if (letters.length == 5 && course.testType.equals("考试")) {
int usualGrade = Integer.parseInt(letters[3]);
int finalGrade = Integer.parseInt(letters[4]);
ExamGrade examGrade = new ExamGrade(usualGrade, finalGrade);
ChooseCourse chooseCourse = new ChooseCourse(course, stu, examGrade);
listChooseCourse.add(chooseCourse);
} else {
System.out.println(stuId + " " + name + " " + ": access mode mismatch");
}
}
}
public boolean checkCourse(Course course) {
int flag1, flag2;
switch (course.getType()) {
case "必修":
flag1 = 0;
break;
case "选修":
flag1 = 1;
break;
default:
flag1 = -1;
break;
}
switch (course.getTestType()) {
case "考试":
flag2 = 0;
break;
case "考察":
flag2 = 1;
break;
default:
flag2 = -1;
break;
}
if (flag1 == 0 && flag2 == 0)
return true;
if (flag1 == 1 && (flag2 == 0 || flag2 == 1))
return true;
System.out.println(course.getCourseName() + " : course type & access mode mismatch");
return false;
}
public Class searchClass(String classId) {
for (Class cls : listClass) {
if (cls.getClassId().equals(classId))
return cls;
}
return null;
}
public Course searchCourse(String name) {
for (Course course : listCourse) {
if (course.getCourseName().equals(name))
return course;
}
return null;
}
public boolean searchStudent(String id) {
for (Student stu : listStudent) {
if (stu.getId().equals(id))
return true;
}
return false;
}
//查找是否有重复选课成绩
public boolean searchChooseCourse(String stuName, String courseName) {
for (ChooseCourse cs : listChooseCourse) {
if (cs.student.getStuName().equals(stuName) && cs.course.getCourseName().equals(courseName))
return true;
}
return false;
}
public void showStudents() {
Collections.sort(listStudent);
for (int i = 0; i < listStudent.size(); i++) {
Student stu = listStudent.get(i);
//从总选课表listChooseCourse中获取该生的选课记录
ArrayList<ChooseCourse> stuCourseSelects = getStudentSelects(stu.getId());
if (stuCourseSelects.size() != 0) {
System.out.println(stu.getId() + " " + stu.getStuName() + " " + getAvgTotalScore(stuCourseSelects));
} else if (stuCourseSelects.size() == 0) {
System.out.println(stu.getId() + " " + stu.getStuName() + " " + "did not take any exams");
}
}
}
public void showCourses() {
Collections.sort(listCourse);
for (int i = 0; i < listCourse.size(); i++) {
Course course = listCourse.get(i);
ArrayList<ChooseCourse> stuCourseSelects = getCourseSelects(course.getCourseName());
if (stuCourseSelects.size() != 0) {
if (course.testType.equals("考试"))
System.out.println(course.getCourseName() + " " + getAvgUsualScore(stuCourseSelects) + " " + getAvgFinalScore(stuCourseSelects) + " " + getAvgTotalScore(stuCourseSelects));
if (course.testType.equals("考察"))
System.out.println(course.getCourseName() + " " + getAvgFinalScore(stuCourseSelects) + " " + getAvgTotalScore(stuCourseSelects));
} else if (stuCourseSelects.size() == 0) {
System.out.println(course.courseName + " " + "has no grades yet");
}
}
}
public void showClasses() {
Collections.sort(listClass);
for (int i = 0; i < listClass.size(); i++) {
Class cls = listClass.get(i);
ArrayList<ChooseCourse> stuCourseSelects = getClassSelects(cls.getClassId());
if (stuCourseSelects.size() != 0) {
System.out.println(cls.getClassId() + " " + getAvgTotalScore(stuCourseSelects));
} else if (stuCourseSelects.size() == 0) {
System.out.println(cls.getClassId() + " " + "has no grades yet");
}
}
}
public ArrayList<ChooseCourse> getStudentSelects(String id) {
ArrayList<ChooseCourse> choose = new ArrayList<>();
for (ChooseCourse cos : listChooseCourse) {
if (cos.student.getId().equals(id))
choose.add(cos);
}
return choose;
}
public ArrayList<ChooseCourse> getCourseSelects(String courseName) {
ArrayList<ChooseCourse> choose = new ArrayList<>();
for (ChooseCourse cos : listChooseCourse) {
if (cos.course.getCourseName().equals(courseName))
choose.add(cos);
}
return choose;
}
public ArrayList<ChooseCourse> getClassSelects(String clsId) {
ArrayList<ChooseCourse> choose = new ArrayList<>();
for (ChooseCourse cos : listChooseCourse) {
if (cos.student.getClsId().equals(clsId))
choose.add(cos);
}
return choose;
}
public int getAvgFinalScore(ArrayList<ChooseCourse> cs) {
int average = 0;
int sum = 0;
for (ChooseCourse c : cs) {
sum += c.grade.finalGrade;
}
average = sum / cs.size();
return average;
}
}
class ChooseCourse {
Course course;
Student student;
Grade grade;
public ChooseCourse(Course course, Student student, Grade grade) {
this.course = course;
this.student = student;
this.grade = grade;
}
}
class Student implements Comparable<Student> {
String stuName;
String id;
String clsId;
public String getId() {
return id;
}
public String getStuName() {
return stuName;
}
public String getClsId() {
return clsId;
}
public Student(String clsId, String id, String stuName) {
this.clsId = clsId;
this.id = id;
this.stuName = stuName;
}
public int compareTo(Student stu) {
return getId().compareTo(stu.getId());
}
}
class Course implements Comparable<Course> {
String courseName;
String type;
String testType;
public Course() {
}
public Course(String courseName, String type, String testType) {
this.courseName = courseName;
this.type = type;
this.testType = testType;
}
public String getCourseName() {
return courseName;
}
public String getType() {
return type;
}
public String getTestType() {
return testType;
}
}
}
class Class implements Comparable<Class> {
String classId;
public Class() {
}
public String getClassId() {
return classId;
}
public Class(String classId) {
this.classId = classId;
}
@Override
public int compareTo(Class o) {
return getClassId().compareTo(o.getClassId());
}
}
abstract class Grade {
int finalGrade;
public Grade() {
}
public abstract int getUsualGrade();
public abstract int getTotalGrade();
}
class ExamGrade extends Grade {
int usualGrade;
public ExamGrade(int usualGrade, int finalGrade) {
this.usualGrade = usualGrade;
this.finalGrade = finalGrade;
}
public int getUsualGrade() {
return usualGrade;
}
public int getFinalGrade() {
return 0;
}
public int getTotalGrade() {
return (int) (usualGrade * 0.3 + finalGrade * 0.7);
}
}
class InputMatching {
static String stuNumMatching = "[0-9]{8}";
static String stuNameMatching = "\\S{1,10}";
static String scoreMatching = "([1-9]?[0-9]|100)";
static String courseNameMatching = "\\S{1,10}";
static String courseTypeMatching = "(选修|必修)";
static String checkCourseTypeMatching = "(考试|考察)";
static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching;
static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching;
static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching + " " + scoreMatching;
public InputMatching() {
}
public int matchingInput(String s) {
if (matchingCourse(s))
return 1;
if (matchingScore(s))
return 2;
return 0;
}
private static boolean matchingCourse(String s) {
return s.matches(courseInput);
}
private static boolean matchingScore(String s) {
if (s.matches(scoreInput1) || s.matches(scoreInput2))
return true;
return false;
}
}
class AssessGrade extends Grade {
public AssessGrade(int finalGrade) {
this.finalGrade = finalGrade;
}
public int getFinalGrade() {
return finalGrade;
}
@Override
public int getUsualGrade() {
return 0;
}
public int getTotalGrade() {
return finalGrade;
}
}
用SourceMonito分析代码所得结果如下:
分析:在这道题目中用了Arraylist容器来储存学生类对象和成绩类对象,并在其他的类中调用该容器中的对象数据,student类中储存学生的有关信息,score类中储存课程信息。
三、踩坑心得:
在这三次作业的解答过程中我遇到了很多问题,现总结如下:
1、在处理判断等腰直角三角形时,一直没有那种近似的转换思想,导致在这个问题上卡了很久,我现在知道该在对应的情况采取最合适的算法来获取正确答案。
2、在对字符输入以及字符多余空格的处理,我不够熟练,有两道题目就是因为字符串后的空格多余而导致测试点始终过不了,我现在学会了用trim()来消除输入时的多余空格,熟练掌握了string类的应用,掌握了string类的很多方法来使字符串符合需求。
3、在创建类时,对于有参构造和无参构造的把握不够熟练,在面向对象数据封装那个题目就遇到了卡壳,最后通过查阅资料。才对他们的应用和区别得以区分。
3、在类的关联以及类之间的相互调用不够清晰,在处理菜单计价问题以及学生成绩问题时,在哪一个类的属性和对象的调用不够清楚,经常存在数据类型和数据定义不批撇而导致报错的情况,例如在order类封装的是record类的对象,但是上面总是用string类的方法来调用他,得益于idea这款软件的调试功能才得以解决报错问题,但是最后还是没有能完成这道题目,很多测试点没有能够通过,关于这道题目代码我还会继续修改。
四、困难及改进建议:
在完成第三次作业时,我明显感到有些力不从心,对于如何处理输入的一大段字符串,将其转化为我所需的内容,这一点需要很多其他类的知识,我还不够熟练,在7-2 课程成绩统计程序-1这道题目里面体现的尤为明显,我采用的方法只能通过几个例子,可能只是几个普通的例子,但在异常情况以及边缘情况时考虑不够完善,并且我写的代码很复杂,ifelse语句太多、太冗余了,导致代码的圈复杂度很高,代码利用率低,在解题时只想着能够通过测试点,却并未考虑到代码的复杂度和复用性。
改进建议:我认为可以适当降低难题和复杂的题目的分数,如在第三次作业中占65分的第二道题,如果对这道题目束手无策,就算其他的题目都满分通过,这次作业也难以及格,所以我认为可以把难题作为优秀学生的挑战性尝试,适当提高平均分。
五、总结:
通过完成这三次pta的作业,我对面向对象的基本过程和知识有了一定的了解,我掌握了类的构建,如何查询java自带的API的应用,常用API的使用,正则表达式的的使用。在一道一道解决题目的过程中,我感受到了面向对象和面向过程的编程的区别,感受到了面向对象编程在优化代码结构,排除冗余代码块的方面所具有的巨大作用,并对其产生了更加浓厚的i兴趣和更加深入的了解。作为没有接触过面向对象的新人,在一开始的解题过程中,我还是偏向于C语言式的面向过程,慢慢转变到面向对象,这个过程不快,导致我有一道题目并未完美解决,在未来我依然会努力加深java的代码量,对面向对象编程的熟悉。