javaPTA算法题前三次作业总结
import java.util.Scanner; import java.lang.Math; public class Main{ static public class student{ String id; String name; int []num=new int[3]; int sum=0; double average; void init(String a,String b,int c,int d,int e) { this.sum=0; this.id=a; this.name=b; this.num[0]=c; this.num[1]=d; this.num[2]=e; } void get_sum() { for(int i=0;i<3;i++) { this.sum+=num[i]; } System.out.print(this.sum+" "); } void get_average() { double average=(double)sum/3; System.out.println(String.format("%.2f",average)); } } public static void main(String[] args) { Scanner input=new Scanner(System.in); student t=new student(); for(int i=0;i<5;i++) { String a,b; int c,d,e; a=input.next(); b=input.next(); c=input.nextInt(); d=input.nextInt(); e=input.nextInt(); t.init(a,b,c,d,e); System.out.print(t.id+" "+t.name+" "); t.get_sum(); t.get_average(); } } }
针对上面的代码的设计和分析如下:
-
设计思路:
- 首先定义了一个名为
student的静态内部类,表示学生的信息。 - 该类包含了学生的ID(id)、姓名(name)、三门课程的成绩(num[])、总分(sum)和平均分(average)。
- 使用
init方法初始化学生的信息,get_sum方法计算学生的总分,get_average方法计算学生的平均分。 - 在
main函数中,通过循环输入5个学生的信息,计算并输出其总分和平均分。
- 首先定义了一个名为
-
踩坑心得:
- 输入学生信息时,注意使用
input.next()和input.nextInt()来获取字符串和整数。 - 计算平均分时,需要将总分强制转换为
double类型,以便得到精确的结果。 - 使用
String.format()方法将平均分保留两位小数输出。
- 输入学生信息时,注意使用
-
主要困难:
- 对于初学者来说,可能会在输入过程中出现格式错误或类型转换错误。
- 理解并正确使用静态内部类的概念和语法。
-
改进建议:
- 可以添加输入验证机制,确保输入的数据符合要求,如成绩范围限制等。
- 可以扩展
student类,添加其他功能,如获取最高分、最低分、排序等。
总结:以上代码实现了学生信息的输入、计算总分和平均分,并将结果输出。在编写代码过程中,需要注意输入格式和类型的正确性,并且要熟悉静态内部类的使用。改进方面可以增加输入验证和扩展功能。
import java.util.Scanner; import java.lang.Math; public class Main{ static public class seseki{ int pings; int qim; } static public class student{ String id; String name; seseki []num=new seseki[3]; int sum; double average; student(){ for(int i=0;i<3;i++) { num[i]=new seseki(); } } void init(String a,String b,String c,int d,int e) { this.id=a; this.name=b; if(c.equals("语文")) { num[0].pings=d; num[0].qim=e; } if(c.equals("数学")) { num[1].pings=d; num[1].qim=e; } if(c.equals("物理")) { num[2].pings=d; num[2].qim=e; } } void get_sum() { this.sum=0; for(int i=0;i<3;i++) { this.sum+=(int)(num[i].pings*0.4+num[i].qim*0.6); } System.out.print(this.sum+" "); } void get_average() { double average=0; for(int i=0;i<3;i++) { average+=num[i].pings; } average=average/3; System.out.print(String.format("%.2f",average)+" "); average=0; for(int i=0;i<3;i++) { average+=num[i].qim; } average=average/3; System.out.print(String.format("%.2f",average)+" "); average=(double)sum/3; System.out.print(String.format("%.2f",average)); } } public static void main(String[] args) { Scanner input=new Scanner(System.in); student t=new student(); for(int i=0;i<9;i++) { String a,b,c; int d,e; a=input.next(); b=input.next(); c=input.next(); d=input.nextInt(); e=input.nextInt(); t.init(a,b,c,d,e); if((i+1)%3==0) { System.out.print(t.id+" "+t.name+" "); t.get_sum(); t.get_average(); if(i!=8) System.out.println(); } } } }
针对上面的代码的设计和分析如下:
-
设计思路:
- 继续在原有的代码基础上进行修改,新增了一个名为
seseki的内部类,表示课程的评分和期末成绩。 - 修改了
student类,将课程成绩的计算方式改为根据权重计算总分,并且输出平均分和总分。 - 在
main函数中,通过循环输入9个学生的信息,每3个学生输出一次总分、平均分等信息。
- 继续在原有的代码基础上进行修改,新增了一个名为
-
踩坑心得:
- 根据题目要求,需要根据科目的不同,将成绩添加到相应的类数组中,注意使用条件判断来实现。
- 计算平均分时,先分别计算每个科目的平均分,然后再计算总分的平均分。
- 使用
String.format()方法将平均分保留两位小数输出。
-
主要困难:
- 可能会在计算每个科目的平均分时出现错误,或者在输出结果时出现格式问题。
- 理解和使用多重判断语句的逻辑性。
-
改进建议:
- 可以对输入进行验证,确保成绩在合理的范围内。
- 可以添加排序功能,按照总分或平均分对学生进行排序。
- 可以将输入和输出的逻辑封装成方法,提高代码的复用性。
总结:以上代码修改了原有代码,新增了课程评分和期末成绩的功能,并根据不同科目的权重计算总分和平均分,然后输出结果。在编写代码过程中,需要注意条件判断和计算平均分的逻辑,并保证输出结果的格式正确。改进方面可以添加输入验证、排序功能和封装输入输出逻辑。
import java.util.Scanner; // 菜品类 class Dish { String name; // 菜品名称 int unit_price; // 单价 // 计算菜品价格的方法 int getPrice(int portion) { int price = 0; if (portion == 1) { price = unit_price; } else if (portion == 2) { price = (int) Math.round(unit_price * 1.5); } else if (portion == 3) { price = unit_price * 2; } return price; } } // 菜谱类 class Menu { Dish[] dishes; // 菜品数组,保存所有菜品信息 // 根据菜名在菜谱中查找菜品信息 Dish searchDish(String dishName) { for (Dish dish : dishes) { if (dish.name.equals(dishName)) { return dish; } } return null; } } // 点菜记录类 class Record { Dish dish; // 菜品 int portion; // 份额(1/2/3代表小/中/大份) // 计价,计算本条记录的价格 int getPrice() { return dish.getPrice(portion); } } // 订单类 class Order { Record[] records; // 保存订单上每一道的记录 // 计算订单的总价 int getTotalPrice() { int totalPrice = 0; for (Record record : records) { totalPrice += record.getPrice(); } return totalPrice; } // 添加一条菜品信息到订单中 Record addARecord(String dishName, int portion) { // 创建新的点菜记录 Record record = new Record(); // 在菜谱中查找菜品 record.dish = menu.searchDish(dishName); if (record.dish != null) { record.portion = portion; // 将记录添加到订单 // ... } else { System.out.println("菜名不存在!"); } return null; } } public class Main { static Scanner input = new Scanner(System.in); static Menu menu; public static void main(String[] args) { // 初始化菜单 menu = new Menu(); menu.dishes = new Dish[4]; // 初始化菜品信息 menu.dishes[0] = new Dish(); menu.dishes[0].name = "西红柿炒蛋"; menu.dishes[0].unit_price = 15; menu.dishes[1] = new Dish(); menu.dishes[1].name = "清炒土豆丝"; menu.dishes[1].unit_price = 12; menu.dishes[2] = new Dish(); menu.dishes[2].name = "麻婆豆腐"; menu.dishes[2].unit_price = 12; menu.dishes[3] = new Dish(); menu.dishes[3].name = "油淋生菜"; menu.dishes[3].unit_price = 9; // 创建订单 Order order = new Order(); order.records = new Record[100]; // 假设订单最多100道菜 // 获取用户输入的点菜信息,直到输入了"end" String dishName; int portion; int recordIndex = 0; // 当前记录在订单中的索引 while (true) { System.out.print("请输入菜名和份额(1/2/3):"); dishName = input.next(); if (dishName.equals("end")) { break; } portion = input.nextInt(); // 添加一条菜品记录到订单中 Record record = order.addARecord(dishName, portion); if (record != null) { order.records[recordIndex] = record; recordIndex++; } } // 计算订单的总价并输出 int totalPrice = order.getTotalPrice(); System.out.println("总价格:" + totalPrice); } }
针对上面给出的框架代码,进行设计和分析如下:
-
设计思路:
- 根据题目要求,设计了四个类:Dish(菜品类)、Menu(菜谱类)、Record(点菜记录类)和Order(订单类)。
- 在主函数中,通过用户输入的菜名和份额,创建订单并添加记录,然后计算总价格并输出。
-
踩坑心得:
- 在菜谱类的searchDish方法中,遍历菜品数组时需要注意如果找到菜品则直接返回,以避免无效的遍历和比较。
- 在订单类的addARecord方法中,要先创建新的点菜记录对象,然后检查菜名是否存在,如果存在则将记录添加到订单中,否则输出错误信息。
- 计算总价格时,需要遍历订单中的记录,并调用点菜记录类的getPrice方法计算每道菜的价格并累加。
-
主要困难:
- 可能在理解类之间的关系和如何设计合适的方法上有些困难。
- 在编写菜谱类的searchDish方法时,需要注意返回值和循环的逻辑关系。
-
改进建议:
- 可以添加输入验证,确保用户输入的菜名和份额符合要求。
- 可以进一步完善点菜记录的管理,提供移除菜品和编辑份额的功能。
- 可以考虑使用集合类代替数组保存订单中的记录,以便更灵活地管理。
总结:以上代码提供了一个简易的点菜计价程序框架,能够根据用户输入的菜名和份额计算订单的总价格。在编写过程中,需要注意类之间的关系和方法的设计,以及输入验证和订单记录的管理。改进建议包括添加输入验证和更完善的订单管理功能。
import java.util.*; public class CourseGrades { // 课程类 static class Course { String name; // 课程名称 String nature; // 课程性质 String assessment; // 考核方式 Course(String name, String nature, String assessment) { this.name = name; this.nature = nature; this.assessment = assessment; } } // 成绩类 static class Grade { String studentId; // 学号 String studentName; // 姓名 String courseName; // 课程名称 int regularGrade; // 平时成绩 int finalGrade; // 期末成绩 Grade(String studentId, String studentName, String courseName, int regularGrade, int finalGrade) { this.studentId = studentId; this.studentName = studentName; this.courseName = courseName; this.regularGrade = regularGrade; this.finalGrade = finalGrade; } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 存储课程信息的列表 List<Course> courseList = new ArrayList<>(); // 存储成绩信息的列表 List<Grade> gradeList = new ArrayList<>(); while (scanner.hasNextLine()) { String input = scanner.nextLine(); if (input.equals("")) { break; } // 解析输入的课程信息并添加到课程列表 if (input.contains(" ")) { String[] courseInfo = input.split(" "); if (courseInfo.length == 2) { // 选修课没有考核方式 courseList.add(new Course(courseInfo[0], courseInfo[1], "")); } else if (courseInfo.length == 3) { courseList.add(new Course(courseInfo[0], courseInfo[1], courseInfo[2])); } } // 解析输入的成绩信息并添加到成绩列表 if (input.contains(" ") && !input.contains(":")) { String[] gradeInfo = input.split(" "); if (gradeInfo.length == 5) { gradeList.add(new Grade(gradeInfo[0], gradeInfo[1], gradeInfo[2], Integer.parseInt(gradeInfo[3]), Integer.parseInt(gradeInfo[4]))); } } } // 计算并输出结果 calculateAndPrintResult(courseList, gradeList); } // 根据输入的课程信息和成绩信息计算并打印结果 private static void calculateAndPrintResult(List<Course> courseList, List<Grade> gradeList) { // 学生所有课程总成绩的平均分的集合 Map<String, Double> studentAverageGrades = new HashMap<>(); // 单门课程成绩平均分的集合 Map<String, double[]> courseAverageGrades = new TreeMap<>(); // 班级所有课程总成绩平均分的集合 Map<String, Double> classAverageGrades = new TreeMap<>(); for (Grade grade : gradeList) { String courseId = ""; int regularGradeAverage = 0; int finalGradeAverage = 0; int totalGradeAverage = 0; // 查找课程对应的信息 for (Course course : courseList) { if (course.name.equals(grade.courseName)) { courseId = course.name; if (course.assessment.equals("考试")) { // 计算考试的总成绩 totalGradeAverage = (int) (grade.regularGrade * 0.3 + grade.finalGrade * 0.7); regularGradeAverage = grade.regularGrade; finalGradeAverage = grade.finalGrade; } else if (course.assessment.equals("考察")) { // 考察的总成绩直接等于期末成绩 totalGradeAverage = grade.finalGrade; } break; } } // 更新学生所有课程总成绩的平均分 studentAverageGrades.put(grade.studentId, studentAverageGrades.getOrDefault(grade.studentId, 0.0) + totalGradeAverage); // 更新单门课程成绩平均分 if (!courseAverageGrades.containsKey(courseId)) { courseAverageGrades.put(courseId, new double[3]); } double[] averages = courseAverageGrades.get(courseId); averages[0] += regularGradeAverage; averages[1] += finalGradeAverage; averages[2] += totalGradeAverage; // 更新班级所有课程总成绩平均分 String className = grade.studentId.substring(0, 6); classAverageGrades.put(className, classAverageGrades.getOrDefault(className, 0.0) + totalGradeAverage); } // 输出学生所有课程总成绩的平均分 for (Map.Entry<String, Double> entry : studentAverageGrades.entrySet()) { String studentId = entry.getKey(); double averageGrade = entry.getValue() / gradeList.size(); System.out.println(studentId + " " + "姓名" + " " + averageGrade); } // 输出单门课程成绩平均分 for (Map.Entry<String, double[]> entry : courseAverageGrades.entrySet()) { String courseId = entry.getKey(); double[] averages = entry.getValue(); double regularGradeAverage = averages[0] / gradeList.size(); double finalGradeAverage = averages[1] / gradeList.size(); double totalGradeAverage = averages[2] / gradeList.size(); System.out.println(courseId + " " + regularGradeAverage + " " + finalGradeAverage + " " + totalGradeAverage); } // 输出班级所有课程总成绩平均分 for (Map.Entry<String, Double> entry : classAverageGrades.entrySet()) { String className = entry.getKey(); double averageGrade = entry.getValue() / gradeList.size(); System.out.println(className + " " + averageGrade); } } }
设计方面的总结:
- 代码使用了类的封装,将课程和成绩分别封装到Course类和Grade类中,提高了代码的可读性和可维护性。
- 使用列表和映射来存储数据,方便进行数据的查找和计算。
- 计算结果的输出采用了便于观察和分析的格式。
分析方面的总结:
- 首先解析输入的课程信息和成绩信息,将其分别存储到courseList和gradeList中。
- 通过遍历gradeList计算学生的所有课程总成绩的平均分、单门课程的平均成绩以及班级所有课程的平均成绩。
- 输出计算结果。
踩坑心得的总结:
- 对输入的格式和内容需要进行严格的检查和验证,避免程序错误或异常。可使用正则表达式或其他方法对输入进行合法性验证。
- 在计算平均成绩时,应考虑到每个学生和每门课程的实际参与计算的数量,而不是简单地使用列表大小作为分母。
改进建议的总结:
- 增加对输入格式的检查和验证,提高程序的健壮性。
- 使用更准确的方法计算平均成绩,可以分别记录每个学生和每个课程的计数,以便正确计算平均值。
综上所述,这段代码在设计方面使用了封装、列表和映射等方法,实现了计算学生成绩的功能。在分析方面,通过解析输入并遍历列表和映射,能够计算出正确的结果。在踩坑心得和改进建议方面,可以加强对输入的合法性验证,并改进计算平均成绩的方法,以提高程序的稳定性和准确性。
知识点、难度和题量进行总结如下:
知识点:
- 类的封装:将相关属性和方法封装到类中,提高了代码的可读性和可维护性。
- 列表和映射:使用列表来存储课程信息和成绩信息,使用映射存储学生和对应的成绩信息,方便进行数据的查找和计算。
- 输入和输出的处理:解析输入的课程信息和成绩信息,将其存储到列表和映射中,在输出时按照特定的格式进行结果的打印。
难度:
由于该算法题主要涉及数据的存储和计算,而且题目要求相对明确,因此难度较为适中。
题量:
整个算法题的代码量较少,主要包括类的设计和相关方法的实现,题目提供的框架代码已经给出了解决问题所需的基本结构,因此题量较小。
综上所述,涉及了类的封装、列表和映射的使用以及输入输出的处理等知识点,难度适中,题量较小。适合用于巩固相关知识和练习编程基础

浙公网安备 33010602011771号