前言:在前三次的题目集中涉及的知识点比较基础,逐步增加难度,题目集一二主要以基础知识数组的运用,类的创建等为主,题目集三难度有所增加,涉及封装思想以及无参有参的构造,需要的代码也比题目集一二有所增加,题目量有所增加。
题目一:菜单计价程序:
某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9
设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)
不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格2。
如果计算出现小数,按四舍五入的规则进行处理。
import java.util.Scanner;
class Dish { private String name; private int unit_price; public Dish(String name, int unit_price) { this.name = name; this.unit_price = unit_price; } public String getName() { return name; } 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 { return -1; } return (int) Math.round(price); } } class Menu { private Dish[] dishes; public Menu(Dish[] dishes) { this.dishes = dishes; } public Dish searchDish(String dishName) { for (Dish dish : dishes) { if (dish.getName().equals(dishName)) { return dish; } } return null; } } class Record { private Dish dish; private int portion; public Record(Dish dish, int portion) { this.dish = dish; this.portion = portion; } public int getPrice() { return dish.getPrice(portion); } } class Order { private Record[] records; public Order() { records = new Record[0]; } public void addARecord(String dishName, int portion, Menu menu) { Dish dish = menu.searchDish(dishName); if (dish != null) { Record record = new Record(dish, portion); Record[] newRecords = new Record[records.length + 1]; for (int i = 0; i < records.length; i++) { newRecords[i] = records[i]; } newRecords[records.length] = record; records = newRecords; } } public int getTotalPrice() { int totalPrice = 0; for (Record record : records) { totalPrice += record.getPrice(); } return totalPrice; } } public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Dish[] dishes = { new Dish("西红柿炒蛋", 15), new Dish("清炒土豆丝", 12), new Dish("麻婆豆腐", 12), new Dish("油淋生菜", 9) }; Menu menu = new Menu(dishes); Order order = new Order(); while (sc.hasNext()) { String input = sc.nextLine(); if (input.equals("end")) { break; } String[] splitInput = input.split(" "); String dishName = splitInput[0]; int portion = Integer.parseInt(splitInput[1]); order.addARecord(dishName, portion, menu); } sc.close(); System.out.println(order.getTotalPrice()); } }
代码分析:
在这道题目中主要涉及的知识点包括类的构建与基本运用,需要在类中构建相应的属性以及函数的构造对应的方法;
比如在dish类中,它的属性包括菜名和菜的基础价格,它的方法包括获取菜名以及基础价格,构造函数接受菜品的名称和单价作为参数,并将其存储在私有成员变量中。获取
菜品名称的方法为getName(),
获取指定份数的菜品总价的方法为getPrice(int portion)。
基础方法中用if语句来对相应的小中大份额进行选择得到具体的价格在后续主函数中可以直接运用。
Menu类表示一个菜单,包含了多个菜品。构造函数接受一个Dish数组作为参数,并将其存储在私有成员变量中。搜索指定菜品名称的方法为searchDish(String dishName),
它会遍历菜单中的所有菜品,
如果找到与指定菜品名称相匹配的菜品,则返回该菜品,否则返回null。
Record类表示一条记录,包含了一道菜品和它的份数。构造函数接受一个Dish对象和一个表示份数的整数作为参数,并将其存储在私有成员变量中。获取该记录的菜品总价的方法为getPrice(),它会调用菜品对象的getPrice(int portion)方法,并返回计算得到的菜品总价。
Order类表示一个订单,包含了多条记录。构造函数初始化一个空的Record数组。添加一条记录的方法为addARecord(String dishName, int portion, Menu menu),它会根据菜品名称在菜单中搜索对应的菜品,并创建一条记录,然后将记录添加到订单中。获取订单总价的方法为getTotalPrice(),它会遍历订单中的所有记录,并累加每条记录的菜品总价,最后返回总价。
Main类是程序的入口点。它使用Scanner类从控制台读取用户的输入,直到输入为"end"为止。每行输入包含菜品名称和份数,通过调用Order对象的addARecord()方法将菜品添加到订单中。最后,调用Order对象的getTotalPrice()方法获取订单的总价。
心得:在这次题目的提交过程中出现多次错误,一开始对private私有变量不太理解,对无参函数和有参函数的构造理解不够到位,总是出现错误,在main中无法使用这些类中的私有变量,导致频繁出错,以及split方法的使用不太明白,出现多次错误,后经过多次改错以及询同学后对相应知识点理解更深了一些,在某个类中对相应的属性进行private修饰后,需要在后续构建一个有参函数,以便main中对该类的函数属性的调用,防止出错,而split方法常用于对一组字符串进行识别,例如时间,生产序号等,利用其中特定的符号进行区分,以上便是我对这道题目的心得。
题目集二7-1
成绩计算-1-类、数组的基本运用:
创建学生类,包含
属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)
方法:计算总分、计算平均分
输入5个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
import java.util.Scanner; class Student { private String id; private String name; private int chineseScore; private int mathScore; private int physicsScore; public Student(String id, String name, int chineseScore, int mathScore, int physicsScore) { this.id = id; this.name = name; this.chineseScore = chineseScore; this.mathScore = mathScore; this.physicsScore = physicsScore; } public int getTotalScore() { return chineseScore + mathScore + physicsScore; } public double getAverageScore() { return Math.round(getTotalScore() / 3.0 * 100) / 100.0; } public String getId() { return id; } public String getName() { return name; } } public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Student[] students = new Student[5]; for (int i = 0; i < 5; i++) { String id = sc.next(); String name = sc.next(); int chineseScore = sc.nextInt(); int mathScore = sc.nextInt(); int physicsScore = sc.nextInt(); students[i] = new Student(id, name, chineseScore, mathScore, physicsScore); } sc.close(); for (Student student : students) { System.out.println(student.getId() + " " + student.getName() + " " + student.getTotalScore() + " " + String.format("%.2f", student.getAverageScore())); } } }
代码分析:
Student类表示一个学生,包含了学生的学号、姓名以及语文、数学和物理三门科目的成绩。构造函数接受学号、姓名和三门科目的成绩作为参数,并将它们存储在私有成员变量中。
获取学生总分的方法为getTotalScore(),它会将三门科目的成绩相加并返回总分。获取学生平均分的方法为getAverageScore(),它会通过调用getTotalScore()方法计算总分,然后
根据总分计算平均分(保留两位小数)。获取学号和姓名的方法为getId()和getName(),它们分别返回学号和姓名。
Main类是程序的入口点。它使用Scanner类从控制台读取五个学生的信息,包括学号、姓名和三门科目的成绩。然后,它创建一个包含五个学生对象的数组,并使用输入的信息
初始化每个学生对象。最后,它遍历学生数组,并调用每个学生对象的方法获取学号、姓名、总分和平均分,并将这些信息打印到控制台。
心得:这是我作业中第一次对类的一个完整构建,此题中只需构建一个学生类,构建相应的属性以及方法,在本道题中出现的错误多为对学生成绩的计算以及对总分计算平均分疏忽保留两位小数,还有对私有成员变量的不理解,对get()和set()方法的初步认识不理解,在后续的知识学习中已经解决这些问题,set()和get()方法中前缀需要带上相对于的类型修饰词,例整数带上int,
浮点数带上double修饰等;
题目集二7-2
成绩计算-2-关联类:
创建成绩类,包含:
属性:平时成绩(int)、期末成绩(int)
方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)
创建学生类,包含:
属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)
方法:计算总分、计算平均分
输入3个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
import java.util.Scanner; class Score { private int dailyScore; private 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 { private String id; private String name; private Score chineseScore; private Score mathScore; private 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 getTotalScore() { return chineseScore.getTotalScore() + mathScore.getTotalScore() + physicsScore.getTotalScore(); } public double getAverageScore() { return Math.round(getTotalScore() / 3.0 * 100) / 100.0; } public String getId() { return id; } public String getName() { return name; } } public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Student[] students = new Student[3]; for (int i = 0; i < 3; i++) { String id = sc.next(); String name = sc.next(); String course = sc.next(); int dailyScore = sc.nextInt(); int finalScore = sc.nextInt(); Score score = new Score(dailyScore, finalScore); if (i == 0) { students[i] = new Student(id, name, score, null, null); } else if (i == 1) { students[i] = new Student(id, name, null, score, null); } else if (i == 2) { students[i] = new Student(id, name, null, null, score); } } sc.close(); for (Student student : students) { System.out.println(student.getId() + " " + student.getName() + " " + student.getTotalScore() + " " + String.format("%.2f", student.getAverageScore())); } } }
代码分析:
Score类表示一门课程的成绩,包含了平时成绩和期末成绩。构造函数接受平时成绩和期末成绩作为参数,并将它们存储在私有成员变量中。获取该门课程总成绩的方法为getTotalScore(),它会根据平时成绩和期末成绩的权重计算出总成绩。
Student类表示一个学生,包含了学号、姓名,以及中文、数学和物理三门课程的成绩。构造函数接受学号、姓名和三门课程的成绩作为参数,并将它们存储在私有成员变量中。获取学生总成绩的方法为getTotalScore(),它会调用每门课程成绩对象的getTotalScore()方法,并将三门课程的总成绩相加。获取学生平均分的方法为getAverageScore(),它会通过调用getTotalScore()方法计算总成绩,然后根据总成绩计算平均分(保留两位小数)。获取学号和姓名的方法为getId()和getName(),分别返回学号和姓名。
Main类是程序的入口点。它使用Scanner类从控制台读取三个学生的信息,包括学号、姓名、课程名称、平时成绩和期末成绩。然后,它创建一个包含三个学生对象的数组,并使用输入的信息初始化每个学生对象。在创建学生对象时,根据学生的位置(i的值),将对应的成绩对象传递给学生对象的构造函数。最后,它遍历学生数组,并调用每个学生对象的方法获取学号、姓名、总成绩和平均分,并将这些信息打印到控制台。
题目集三7-2
课程成绩统计程序:
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Scanner; class Course { private String name; private String nature; private String assessmentMode; public Course(String name, String nature, String assessmentMode) { this.name = name; this.nature = nature; this.assessmentMode = assessmentMode; } public String getName() { return name; } public String getNature() { return nature; } public String getAssessmentMode() { return assessmentMode; } } class Grade { private String sid; private String name; private String courseName; private int dailyGrade; private int finalGrade; public Grade(String sid, String name, String courseName, int dailyGrade, int finalGrade) { this.sid = sid; this.name = name; this.courseName = courseName; this.dailyGrade = dailyGrade; this.finalGrade = finalGrade; } public String getSid() { return sid; } public String getName() { return name; } public String getCourseName() { return courseName; } public int getDailyGrade() { return dailyGrade; } public int getFinalGrade() { return finalGrade; } } public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); List<Course> courses = new ArrayList<>(); List<Grade> grades = new ArrayList<>(); while (sc.hasNext()) { String input = sc.nextLine(); if (input.equals("end")) { break; } String[] splitInput = input.split(" "); if (splitInput.length == 3) { String courseName = splitInput[0]; String nature = splitInput[1]; String assessmentMode = splitInput[2]; courses.add(new Course(courseName, nature, assessmentMode)); } else if (splitInput.length == 6) { String sid = splitInput[0]; String name = splitInput[1]; String courseName = splitInput[2]; int dailyGrade = Integer.parseInt(splitInput[3]); int finalGrade = Integer.parseInt(splitInput[4]); grades.add(new Grade(sid, name, courseName, dailyGrade, finalGrade)); } } sc.close(); List<String> studentGrades = new ArrayList<>(); List<String> courseAverages = new ArrayList<>(); List<String> classAverages = new ArrayList<>(); for (Grade grade : grades) { String sid = grade.getSid(); String name = grade.getName(); String courseName = grade.getCourseName(); int dailyGrade = grade.getDailyGrade(); int finalGrade = grade.getFinalGrade(); Course course = findCourseByName(courseName, courses); if (course == null) { String message = sid + " " + name + ": " + courseName + " does not exist"; studentGrades.add(message); continue; } String nature = course.getNature(); String assessmentMode = course.getAssessmentMode(); if (!isAssessmentModeValid(dailyGrade, finalGrade, assessmentMode)) { String message = sid + " " + name + ": access mode mismatch"; studentGrades.add(message); continue; } if (!isNatureValid(nature, assessmentMode)) { String message = courseName + " : course type & access mode mismatch"; courseAverages.add(message); continue; } if (assessmentMode.equals("考试")) { int totalGrade = calculateTotalGrade(dailyGrade, finalGrade); studentGrades.add(sid + " " + name + " " + totalGrade); } else if (assessmentMode.equals("考察")) { int totalGrade = finalGrade; studentGrades.add(sid + " " + name + " " + totalGrade); } } for (Course course : courses) { String courseName = course.getName(); String nature = course.getNature(); String assessmentMode = course.getAssessmentMode(); List<Integer> dailyGrades = new ArrayList<>(); List<Integer> finalGrades = new ArrayList<>(); List<Integer> totalGrades = new ArrayList<>(); for (Grade grade : grades) { String courseNameGrades = grade.getCourseName(); if (courseNameGrades.equals(courseName)) { int dailyGrade = grade.getDailyGrade(); int finalGrade = grade.getFinalGrade(); dailyGrades.add(dailyGrade); finalGrades.add(finalGrade); if (assessmentMode.equals("考试")) { int totalGrade = calculateTotalGrade(dailyGrade, finalGrade); totalGrades.add(totalGrade); } else if (assessmentMode.equals("考察")) { totalGrades.add(finalGrade); } } } if (dailyGrades.isEmpty() && finalGrades.isEmpty()) { String message = courseName + " has no grades yet"; courseAverages.add(message); continue; } int dailyGradeAverage = calculateAverage(dailyGrades); int finalGradeAverage = calculateAverage(finalGrades); int totalGradeAverage = calculateAverage(totalGrades); courseAverages.add(courseName + " " + dailyGradeAverage + " " + finalGradeAverage + " " + totalGradeAverage); } List<String> classGrades = calculateClassGrades(grades, courses); classGrades.sort(new ClassGradeComparator()); for (String grade : studentGrades) { System.out.println(grade); } for (String average : courseAverages) { System.out.println(average); } for (String classGrade : classGrades) { System.out.println(classGrade); } } private static Course findCourseByName(String courseName, List<Course> courses) { for (Course course : courses) { if (course.getName().equals(courseName)) { return course; } } return null; } private static boolean isAssessmentModeValid(int dailyGrade, int finalGrade, String assessmentMode) { if (assessmentMode.equals("考试")) { return dailyGrade >= 0 && dailyGrade <= 100 && finalGrade >= 0 && finalGrade <= 100; } else if (assessmentMode.equals("考察")) { return dailyGrade == 0 && finalGrade >= 0 && finalGrade <= 100; } return false; } private static boolean isNatureValid(String nature, String assessmentMode) { if (nature.equals("必修")) { return assessmentMode.equals("考试"); } else if (nature.equals("选修")) { return assessmentMode.equals("考试") || assessmentMode.equals("考察"); } return false; } private static int calculateTotalGrade(int dailyGrade, int finalGrade) { double dailyWeight = 0.3; double finalWeight = 0.7; return (int) Math.round(dailyGrade * dailyWeight + finalGrade * finalWeight); } private static int calculateAverage(List<Integer> grades) { int sum = 0; for (int grade : grades) { sum += grade; } return sum / grades.size(); } private static List<String> calculateClassGrades(List<Grade> grades, List<Course> courses) { List<String> classGrades = new ArrayList<>(); List<String> classNames = new ArrayList<>(); for (Grade grade : grades) { String sid = grade.getSid(); classNames.add(sid.substring(0, 6)); } List<String> distinctClassNames = new ArrayList<>(); for (String className : classNames) { if (!distinctClassNames.contains(className)) { distinctClassNames.add(className); } } for (String className : distinctClassNames) { List<Integer> totalGrades = new ArrayList<>(); for (Grade grade : grades) { String sid = grade.getSid(); String courseName = grade.getCourseName(); int dailyGrade = grade.getDailyGrade(); int finalGrade = grade.getFinalGrade(); Course course = findCourseByName(courseName, courses); if (course == null) { continue; } String nature = course.getNature(); String assessmentMode = course.getAssessmentMode(); if (!isAssessmentModeValid(dailyGrade, finalGrade, assessmentMode)) { continue; } if (!isNatureValid(nature, assessmentMode)) { continue; } if (sid.substring(0, 6).equals(className) && assessmentMode.equals("考试")) { int totalGrade = calculateTotalGrade(dailyGrade, finalGrade); totalGrades.add(totalGrade); } } if (totalGrades.isEmpty()) { classGrades.add(className + " has no grades yet"); continue; } int totalGradeAverage = calculateAverage(totalGrades); classGrades.add(className + " " + totalGradeAverage); } return classGrades; } } class ClassGradeComparator implements Comparator<String> { public int compare(String s1, String s2) { int grade1 = Integer.parseInt(s1.split(" ")[1]); int grade2 = Integer.parseInt(s2.split(" ")[1]); return Integer.compare(grade1, grade2); } }
代码分析:
Grade类表示一条成绩记录,包含了学生的学号、姓名、课程名称以及每日成绩和期末成绩。它提供了获取每日成绩和期末成绩的方法。
Course类表示一门课程,包含了课程的名称、性质(必修或选修)以及考核方式(考试或考察)。
Main类是程序的入口点。它使用Scanner类从控制台读取输入信息,包括课程和成绩的相关信息。然后,它根据输入信息创建Course对象和Grade对象,并将它们存储在List<Course>和List<Grade>中。接下来,它使用这些对象进行一系列的操作,包括验证成绩的有效性、计算学生和课程的平均成绩,以及计算班级的平均成绩。最后,它将所有结果打印到控制台。
ClassGradeComparator是一个比较器,用于排序班级的平均成绩。
Main类的main方法是程序的入口点。它首先创建一个Scanner对象来读取控制台输入。创建两个空的ArrayList对象courses和grades,用于存储课程和成绩的信息。使用while循环读取输入,当输入为"end"时跳出循环。根据输入的格式进行切割,如果切割后的数组长度为3,则表示输入的是课程信息,根据切割后的元素创建Course对象,并将其添加到courses列表中。如果切割后的数组长度为6,则表示输入的是成绩信息,根据切割后的元素创建Grade对象,并将其添加到grades列表中。关闭Scanner对象。
创建三个空的ArrayList对象studentGrades、courseAverages和classAverages,用于存储学生的成绩、课程的平均成绩和班级的平均成绩。遍历grades列表,对每个成绩进行处理。首先获取学号、姓名、课程名称、每日成绩和期末成绩。然后根据课程名称在courses列表中查找对应的课程对象。如果找不到对应的课程对象,则将错误信息添加到studentGrades列表中。获取课程的性质和考核方式,并检查成绩的有效性。如果性质和考核方式不匹配,则将错误信息添加到courseAverages列表中。根据考核方式计算学生的总成绩,并将学生的成绩信息添加到studentGrades列表中。遍历courses列表,对每门课程进行处理。获取课程的名称、性质和考核方式。创建三个空的ArrayList对象dailyGrades、finalGrades和totalGrades,用于存储每门课程的每日成绩、期末成绩和总成绩。遍历grades列表,对每个成绩进行处理。如果成绩的课程名称与当前课程名称相匹配,则将每日成绩和期末成绩添加到对应的列表中。如果每日成绩和期末成绩的列表都为空,则将错误信息添加到courseAverages列表中。计算每门课程的每日成绩、期末成绩和总成绩的平均值,并将平均值添加到courseAverages列表中。调用calculateClassGrades方法计算班级的平均成绩,并将结果存储在classGrades列表中。使用ClassGradeComparator比较器对classGrades列表进行排序。遍历studentGrades列表,将学生的成绩信息打印到控制台。遍历courseAverages列表,将课程的平均成绩信息打印到控制台。遍历classGrades列表,将班级的平均成绩信息打印到控制台。
Main类中的findCourseByName方法用于根据课程名称查找对应的课程对象。Main类中的isAssessmentModeValid方法用于检查成绩的有效性。Main类中的isNatureValid方法用于检查课程性质和考核方式是否匹配。Main类中的calculateTotalGrade方法用于计算总成绩。Main类中的calculateAverage方法用于计算平均值。Main类中的calculateClassGrades方法用于计算班级的平均成绩。
ClassGradeComparator类实现了Comparator接口,用于对班级的平均成绩进行比较。
心得:这道题的代码量较多,出现了很多次出错,需要做一个完整的课程成绩统计,虽然只需要构建三个类,但是涉及的函数方法以及数学计算比较多,以及初次对Arraylist和List<>的认识不太理解,其次本题中容易疏忽很多细节,例如忘记对成绩有效性的判定,平均值计算是否采用保留小数,对考试与考察的理解不够到位。
主要困难:在这道题中,在idea软件中可以实现具体相对应的操作,并且不会出错,但在pta中却显示答案错误,可能是某段代码中函数里面的计算有点问题,但是没有找出来,在iead编译器里面对输入的数据都能输出正确的结果。
总结:在本阶段三次题目集,我有了较大进步,学习了java中类的构建,类方法和类变量的具体应用,封装思想的应用,封装的访问属性和开放的访问属性,二维数组的应用,对java中的很多方法有了初步的了解,Arraylist的操作等等,但是对java封装思想以及许多方法的使用不太熟悉,仍需进行大量的练习,另外对私有变量以及开放变量的区别理解不是很深,需要进一步的学习。对老师课程,线下教学目前没有改进建议和意见