Java题目集第一次总结

发布时间 2023-10-07 21:59:41作者: 不会代码的小陈

前言

此Blog是对Java的PTA作业的总结,旨在分析和总结所做过的Java题目,以加深对Java的理解和加强对Java的运用。

前三次PTA中涉及到了类和数组的基本运用,字符串的操作,数据的封装,日期类的方法的基本运用等知识点。

第一次作业题量适中,难度也适中;第二次作业题量偏多,难度偏大;第三次作业虽然题量不多,但是难度大大提升。

PTA第一次作业

(这是我第一次接触Java,Java作为一门面向对象的语言,在编程逻辑上和C语言有所不同,但逻辑思路上和C语言相似,主要是学习Java中的各类方法和对对象操作的思路)

第一次PTA作业主要是让我们认识Java这门语言,在Java中,所有操作都需要放在类里面进行。

我选择其中一道“二进制数值提取”题目为例,分享我学习Java的过程。

该题的输入格式要求:

一个由0、1构成的序列,以-1为结束符,非0、1字符视为正常输入,但忽略不计,未包含结束符的序列视为非法输入。例如:abc00aj014421-1

输出格式要求:

将输入的序列去掉非0、1字符以及结尾符的数据内容。
注:结束符-1之后的0\1字符忽略不计。
例如:00011。

经过分析,该题主要是对输入的数据进行筛选,选择需要的数据输出。

通过查询资料,我学习到了Java中对字符串操作的方法,因此顺利的完成了这道题目。

源代码如下:

 1 import java.util.Scanner;
 2 import java.lang.StringBuffer;
 3 
 4 public class Main{
 5     public static void main(String[] args){
 6         Scanner input=new Scanner(System.in);
 7         String chars=input.nextLine();
 8         int location=chars.indexOf("-1");
 9         if (location==-1)
10             System.out.println("Wrong Format");
11         else {
12             String cut=chars.substring(0,location);
13             for (int i=0;i<cut.length();i++)
14             {
15                 if (cut.charAt(i)=='0'||cut.charAt(i)=='1')
16                     System.out.print(cut.charAt(i));
17             }
18         }
19     }
20 }

 

PTA第二次作业

第二次PTA作业就开始涉及面向对象的操作了,我们需要自己创建类,并且在类里写上该类的一些操作方法。对于复杂的题目,我们还需要创建类图以便于更直观的分析题目。

在此次作业中,我将以7-1、7-2和7-7为例,分析Java的学习思路。

7-1和7-2都是强化我们对Java中类的理解和运用,以及类与类之间如何关联起来。因此我将两道题目合并起来分析。

首先给出题目:

(7-1)创建学生类,包含

属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)

方法:计算总分、计算平均分

输入5个学生的信息,将每个学生的信息封装在一个学生对象中。

按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

(7-2)创建成绩类,包含:

属性:平时成绩(int)、期末成绩(int)

方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)

创建学生类,包含:

属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)

方法:计算总分、计算平均分

输入3个学生的信息,将每个学生的信息封装在一个学生对象中。

按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

分析题目可知,这两题都需要创建学生类对象,然后对学生的成绩数据进行计算,最后输出。

由于Java的编程逻辑是将方法和对象结合起来操作,因此学生成绩的计算方法应该和学生类绑定,而第二题中则需要新增总成绩类,思路大致相同。

(7-1)源代码如下:

 

 1 import java.util.Scanner;
 2 
 3 public class Main{
 4     public static void main(String[] args){
 5         Scanner input = new Scanner(System.in);
 6         Student[] stus=new Student[5];
 7         for (int i=0;i<5;i++)
 8         stus[i] = new Student();        
 9         for (int i=0;i<5;i++)
10         {
11             stus[i].stu_id=input.next();
12             stus[i].name=input.next();
13             stus[i].chinese=input.nextInt();
14             stus[i].math=input.nextInt();
15             stus[i].physical=input.nextInt();
16             }
17         for (int i=0;i<5;i++)
18             System.out.printf("%s %s %d %.2f\n",stus[i].stu_id,stus[i].name,stus[i].all_score(),stus[i].average());
19     }
20        public static class Student{
21         private String stu_id;
22        private String name;
23        private int chinese;
24        private int math;
25        private int physical;
26         public int all_score(){
27             return chinese+math+physical;
28         }
29         public double average(){
30             return (chinese+math+physical)/3.0;
31         }
32 }
33 }

 

(7-2)源代码如下:

 

 1 import java.util.Scanner;
 2 
 3 public class Main{
 4     public static void main(String[] args){
 5         Scanner input = new Scanner(System.in);
 6         Student[] stus=new Student[3];
 7         Score[][] stu_score=new Score[3][3];
 8         for (int i=0;i<3;i++){
 9             for (int j=0;j<3;j++){
10                 stus[i] = new Student();
11                 stu_score[i][j] = new Score();
12                 stus[i].studentID=input.next();
13                 stus[i].studentname=input.next();
14                 String a=input.next();
15                 stu_score[i][j].peacetime_grades=input.nextInt();
16                 stu_score[i][j].final_grades=input.nextInt();
17             }
18             stus[i].chinese=stu_score[i][0].score();
19             stus[i].math=stu_score[i][1].score();
20             stus[i].physical=stu_score[i][2].score();
21         }
22         for (int i=0;i<3;i++)
23         {
24             System.out.printf("%s %s %d %.2f %.2f %.2f\n",stus[i].studentID,stus[i].studentname,stus[i].all_score(),stus[i].average(stu_score[i][0].peacetime_grades,stu_score[i][1].peacetime_grades,stu_score[i][2].peacetime_grades),stus[i].average(stu_score[i][0].final_grades,stu_score[i][1].final_grades,stu_score[i][2].final_grades),stus[i].average(stus[i].chinese,stus[i].math,stus[i].physical));
25         }
26     }
27     public static class Score{
28         int peacetime_grades;
29         int final_grades;
30         public int score(){
31             return (int)(peacetime_grades*0.4+final_grades*0.6);
32         }
33     }
34     public static class Student{
35         private String studentID;
36         private String studentname;
37         private int chinese;
38         private int math;
39         private int physical;
40     
41     public int all_score(){
42             return chinese+math+physical;
43         }
44         public double average(int x,int y,int z){
45             return (x+y+z)/3.0;
46         }
47     }
48 }

 

 由于这两题比较简单,因此不创建类图和复杂度分析。

7-7这一题,相较前面的题目难度大了很多,需要我们做出一个菜单计价系统。

题目要求如下:

某饭店提供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)
//添加一条菜品信息到订单中。
}

 该题给出了类的部分定义,需要我们通过这些类的定义完善整个系统。

分析该题目可知,各类之间存在这一定的联系,找到这些联系之后,便可以将各类关联起来,然后进行价格的计算。

Java是一门面向对象的编程,因此从对象操作开始入手。

创建类图,对每个类进行分析之后便可以得到各类的操作方法,随后将各类联系起来便可以完善该系统。

类图如下:

  • Dish 类:表示一个菜品,包含菜品名称 name 和单价 unit_price。通过 getPrice 方法根据份数计算价格。
  • Menu 类:表示菜单,包含菜品数组 dishs 和 searchDish 方法用于查找菜品。
  • Record 类:表示一条点餐记录,包含菜品 d 和份数 portion。通过 getPrice 方法获取该记录的价格。
  • Order 类:表示订单,包含点餐记录数组 records、菜单对象 menu 和相应的操作方法。

源代码如下:

  1 import java.util.Scanner;
  2 
  3 public class Main {
  4     public static void main(String[] args) {
  5         Scanner input = new Scanner(System.in);
  6         Order ord = new Order();
  7         int i = 0;
  8         while (true) {
  9             String dishName = input.next();
 10             if (dishName.equalsIgnoreCase("end"))
 11                 break;
 12             int portion = input.nextInt();
 13             if (ord.addARecord(dishName, portion) == null)
 14                 System.out.println(dishName + " does not exist");
 15             else ord.records[i++] = ord.addARecord(dishName, portion);
 16         }
 17 
 18         System.out.println(ord.getTotalPrice());
 19     }
 20 
 21     public static class Dish {
 22         String name;
 23         int unit_price;
 24 
 25         public Dish(String name, int unit_price) {
 26             this.name = name;
 27             this.unit_price = unit_price;
 28         }
 29 
 30         int getPrice(int portion) {
 31             double price = 0;
 32             switch (portion) {
 33                 case 1:
 34                     price = unit_price;
 35                     break;
 36                 case 2:
 37                     price = 1.5 * unit_price;
 38                     break;
 39                 case 3:
 40                     price = 2 * unit_price;
 41                     break;
 42             }
 43             return (int) Math.round(price);
 44         }
 45     }
 46 
 47     public static class Menu {
 48         Dish[] dishs;
 49 
 50         public Menu() {
 51             dishs = new Dish[4];
 52             dishs[0] = new Dish("西红柿炒蛋", 15);
 53             dishs[1] = new Dish("清炒土豆丝", 12);
 54             dishs[2] = new Dish("麻婆豆腐", 12);
 55             dishs[3] = new Dish("油淋生菜", 9);
 56         }
 57 
 58         Dish searchDish(String dishName) {
 59             for (int i=0;i<4;i++) {
 60                 if (dishs[i].name.equals(dishName)) {
 61                     return dishs[i];
 62                 }
 63             }
 64             return null;
 65         }
 66     }
 67 
 68     public static class Record {
 69         Dish d;
 70         int portion;
 71 
 72         int getPrice() {
 73             return d.getPrice(portion);
 74         }
 75     }
 76 
 77     public static class Order {
 78         Record[] records = new Record[10];
 79         Menu menu;
 80 
 81         public Order() {
 82             menu = new Menu();
 83         }
 84 
 85         int getTotalPrice() {
 86             int total = 0;
 87             int i=0;
 88             while ( records[i]!=null) {
 89                 total += records[i++].getPrice();
 90             }
 91             return total;
 92         }
 93 
 94         Record addARecord(String dishName, int portion) {
 95             Dish foundDish = menu.searchDish(dishName);
 96             if (foundDish == null) {
 97                 return null;
 98             } else {
 99                 Record a = new Record();
100                 a.d = foundDish;
101                 a.portion = portion;
102                 return a;
103 
104 
105             }
106         }
107     }
108 }

 此代码的复杂度分析如下:

代码流程分析如下:

  • 创建 Scanner 对象 input,用于接收用户输入。
  • 创建 Order 对象 ord
  • 使用循环读取用户输入的菜品名称和份数,直到输入 "end" 为止。
  • 根据菜品名称和份数调用 addARecord 方法创建一条点餐记录,如果菜品不存在则返回 null
  • 如果点餐记录不为空,将其存储在 records 数组中。
  • 输出订单的总价格,即调用 getTotalPrice 方法。

 第二次PTA题目总结:通过此次作业,我加深了对类的理解,掌握了对类的运用,各类的方法操作,和日期类的基本运用。此次作业将类与类之间关联起来操作,使我对Java的编程运用更加灵活。

PTA第三次作业

此次作业中,难度最大的便是7-2:课程成绩统计程序。

因此,在此次作业中,只对该题进行分析。

7-2题目要求如下:

某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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)成绩平均分只取整数部分,小数部分丢弃

该题复杂度很高,相较于上一次作业的“菜单计价系统”,该题对类之间的联系更加紧密,逻辑要求更高,需要将各类串联起来才能完成该题。

首先我们需要创建四个对象,分别是班级类、学生类、课程类和成绩类。在这些类中,我们还要写出成绩计算的方法操作。

根据题目分析可知,学生类需要和班级类关联,成绩又需要和班级关联;成绩类和课程类都要和学生类联系在一起,成绩类又要和课程类关联在一起。

基于这样的逻辑,我们需要在各类中创建其他类的数组以便于关联,在主程序中有逻辑的调用这些类,以便于数据的存入和读取,还需要对数据的格式、是否超出范围进行判定。

因此,类图创建如下:

course_abstract是一个抽象类,用于定义课程的基本属性,包括课程名称、考核方式、平时成绩和考试成绩。它还有一个抽象方法getscores(),用于计算课程的总分,具体的总分计算由子类实现。

course类继承自course_abstract,表示具体的课程对象,包含了课程名称、属性、考核方式、总分、平时成绩总分和考试成绩总分等属性。它重写了父类的getscores()方法,根据考核方式计算总分。

student类表示学生对象,包含学号、姓名、选修课程列表等属性。每个学生对象可以选择多门课程,并将其存储在一个选修课程列表中。

s_class类表示班级对象,包含班号和成绩等属性。每个班级对象包含多个学生对象。

 源代码如下:

  1 import  java.util.Scanner;
  2 import java.util.regex.Pattern;
  3 import java.util.regex.Matcher;
  4 
  5 public class Main{
  6     private static String s_id = "^\\d{8}$";//学号
  7     public static void main(String[] args) {
  8         Scanner input = new Scanner(System.in);
  9         String[] put;
 10         course[] Course=new course[10];
 11         student[] Student=new student[20];
 12         s_class[] Class=new s_class[10];
 13         String flag="";
 14         String flag1="";
 15         String flag2="";
 16         int i=0,j=0,k=0,l=0,b=0;
 17         boolean pue = true;
 18         while (true) {
 19             String obtain = input.nextLine();
 20             if (obtain.equalsIgnoreCase("end"))
 21                 break;
 22             put = obtain.split(" ");
 23             if (put.length<=3){
 24                 if (flag2.equals(put[0]))
 25                     ;
 26                 else {
 27                     flag2 = put[0];
 28                 Course[i]=new course(put[0],put[1]);
 29                 if (put[1].equals("必修"))
 30                     Course[i].setmode("考试");
 31                 else Course[i].setmode("考察");
 32                 if (put[1].equals("必修")&&put[2].equals("考察")){
 33                     System.out.println(put[0]+" : course type & access mode mismatch");
 34                     Course[i]=null;
 35                 }
 36                 i++;}
 37             }
 38             else {
 39                 i=0;
 40                 if (!flag1.equals(put[0].substring(0,6)))
 41                 {
 42                     Class[l] = new s_class(put[0].substring(0,6));
 43                     flag1 = Class[l++].classid;
 44                 }
 45                 if (!flag.equals(put[0])) {
 46                     Student[j++] = new student(put[0], put[1]);
 47                     flag=put[0];
 48                     k=0;
 49                 }
 50                 Student[j-1].course[k]=new course_abstract(put[2]);
 51                 for (course a:Course){
 52                     if (a!=null)
 53                         if (Student[j-1].course[k].name.equals(a.name)) {
 54                             Student[j-1].course[k].setmode(a.mode);
 55                             b=i;
 56                     }
 57                     i++;
 58                 }
 59                 if (Student[j-1].course[k].mode==null)
 60                 {
 61                     System.out.println(Student[j-1].id+" "+Student[j-1].name+" : "+put[2]+" does not exist");
 62                 }
 63                 else if (Student[j-1].course[k].mode.equals("考试")&&put.length==4)
 64                         System.out.println(Student[j-1].id+" "+Student[j-1].name+" : access mode mismatch");
 65                 else if(put.length==4){
 66                     if (Integer.parseInt(put[3])>=0&&Integer.parseInt(put[3])<=100){
 67                         Student[j-1].course[k].final1=Integer.parseInt(put[3]);
 68                         Course[b].setfinal(Integer.parseInt(put[3]));
 69                         Course[b].setall();}
 70                     else System.out.println("wrong format");
 71                 }
 72                 else {
 73                     if ((Integer.parseInt(put[3])>=0&&Integer.parseInt(put[3])<=100)&&(Integer.parseInt(put[4])>=0&&Integer.parseInt(put[4])<=100)){
 74                         Student[j-1].course[k].usual=Integer.parseInt(put[3]);
 75                         Student[j-1].course[k].final1=Integer.parseInt(put[4]);
 76                         Course[b].setusual(Integer.parseInt(put[3]));
 77                         Course[b].setfinal(Integer.parseInt(put[4]));
 78                         Course[b].setall();}
 79                     else System.out.println("wrong format");
 80                 }
 81                 Class[l-1].setall(Student[j-1].course[k++].getscores());
 82             }
 83         }
 84         Pattern q = Pattern.compile(s_id);
 85         Matcher n;
 86         Student = student_sort(Student);
 87         Class = class_sort(Class);
 88         Course = course_sort(Course);
 89         for (student a:Student){
 90             if (a!=null) {
 91                 n = q.matcher(a.id);
 92                 if (a.name.length()<=10 && n.matches())
 93                     if (a.all_scores() <= 0)
 94                         System.out.println(a.id + " " + a.name + " did not take any exams");
 95                     else System.out.println(a.id + " " + a.name + " " + a.all_scores());
 96                 else System.out.println("wrong format");
 97             }
 98         }
 99         for (course a: Course){
100             if (a!=null) {
101                 if (a.name.length()<=10)
102                     if (a.get_allaverage() <= 0)
103                         System.out.println(a.name + " has no grades yet");
104                     else if (a.get_uaverage() != 0) {
105                         System.out.println(a.name + " " + a.get_uaverage() + " " + a.get_faverage() + " " + a.get_allaverage());
106                     } else System.out.println(a.name + " " + a.get_faverage() + " " + a.get_allaverage());
107                 else System.out.println("wrong format");
108             }
109         }
110         for (s_class a:Class){
111             if (a!=null) {
112                 if (a.all_average() <= 0)
113                     System.out.println(a.classid + " has no grades yet");
114                 else System.out.println(a.classid + " " + a.all_average());
115             }
116         }
117     }
118     public static student[] student_sort(student[] a){
119         for (int i=0;i<a.length-1;i++)
120             for (int j=0;j<a.length-i-1;j++)
121                 if (a[j+1]!=null)
122                     if (Integer.parseInt(a[j].id)>Integer.parseInt(a[j+1].id)) {
123                         student temp = a[j];
124                         a[j] = a[j + 1];
125                         a[j + 1] = temp;
126                     }
127     return a;
128     }
129     public static s_class[] class_sort(s_class[] a){
130         for (int i=0;i<a.length-1;i++)
131             for (int j=0;j<a.length-i-1;j++)
132                 if (a[j+1]!=null)
133                     if (Integer.parseInt(a[j].classid)>Integer.parseInt(a[j+1].classid)) {
134                         s_class temp = a[j];
135                         a[j] = a[j + 1];
136                         a[j + 1] = temp;
137                     }
138         return a;
139     }
140     public static course[] course_sort(course[] a){
141         for (int i=0;i<a.length-1;i++)
142             for (int j=0;j<a.length-i-1;j++)
143                 if (a[j+1]!=null)
144                     if (a[j].name.charAt(0)>a[j+1].name.charAt(0)) {
145                         course temp = a[j];
146                         a[j] = a[j + 1];
147                         a[j + 1] = temp;
148                     }
149         return a;
150     }
151 }
152 class s_class{
153     String classid;
154     int all=0;
155     int count=0;
156     public s_class(String classid){
157         this.classid=classid;
158     }
159     public void setall(int scores){
160         this.all+=scores;
161         count++;
162     }
163     public int all_average(){
164         if (count==0)
165             return all;
166         return all/count;
167     }
168 }
169 
170 class student{
171     String id;
172     String name;
173     course_abstract[] course;
174     public student(String id,String name){
175         this.id= id;
176         this.name= name;
177         course = new course_abstract[10];
178     }
179     public int all_scores(){
180         int all=0;
181         int count=0;
182         for (course_abstract Course:course){
183             if (Course!=null) {
184                 all += Course.getscores();
185                 count++;
186             }
187         }
188         if (count==0)
189             return all;
190         return all/count;
191     }
192 }
193 class course{
194     String name;
195     String properties;
196     String mode;
197     course_abstract couese;
198     int all;
199     int allusual=0;
200     int allfinal=0;
201     int count;
202     public course(String name,String properties){
203         this.name=name;
204         this.properties=properties;
205         this.count=0;
206         this.all=0;
207         couese = new course_abstract(name);
208         couese.setusual(0);
209         couese.setfanal1(0);
210     }
211     public void setmode(String mode){
212         couese.setmode(mode);
213         this.mode=mode;
214     }
215     public void setusual(int usual){
216         couese.usual=usual;
217         this.allusual+=usual;
218     }
219     public void setfinal(int final1){
220         couese.final1=final1;
221         this.allfinal+=final1;
222     }
223     public void setall(){
224         this.all+=couese.getscores();
225         this.count++;
226     }
227     public int get_uaverage(){
228         return allusual/count;
229     }
230     public int get_faverage(){
231         return allfinal/count;
232     }
233     public int get_allaverage(){
234         if (count==0)
235             return all;
236         return all/count;
237     }
238 }
239 class course_abstract{
240     String name;
241     String mode;
242     int usual=-1;
243     int final1=-1;
244     public course_abstract(String name){
245         this.name = name;
246     }
247     public void setmode(String mode){
248         this.mode= mode;
249     }
250     public void setusual(int usual){
251         this.usual= usual;
252     }
253     public void setfanal1(int final1){
254         this.final1= final1;
255     }
256     public int getscores(){
257         if (mode!=null){
258         if (mode.equals("考察"))
259             return final1;
260         if (mode.equals("考试")) {
261             if (usual==-1||final1==-1)
262                 return 0;
263             return (int) (usual * 0.3 + final1 * 0.7);
264         }
265         }
266         return (int)(usual*0.3+final1*0.7);
267     }
268 }

此代码的复杂度分析如下:

 代码流程分析如下:

  • 定义一些变量和对象,如存储课程、学生和班级信息的数组,以及用于输入的 Scanner 对象等。
  • 进入 while 循环,读取输入的每一行,并根据空格分割字符串,将输入分为三种类型:课程信息、班级信息、学生成绩信息。
  • 如果输入为课程信息,将课程存入课程数组中,判断课程属性是否正确,然后将课程加入课程数组。
  • 如果输入为班级信息,将班号存入班级数组中,检查是否需要新建班级,如果是则创建新的班级对象。检查学生是否已存在,如果不存在,则创建学生对象并添加到学生数组中。将学生的选课信息存入相应的课程对象中,并根据考核方式进行处理。
  • 如果输入为学生成绩信息,查询该学生是否选择了该门课程,如果是,则将成绩信息存入课程对象中,并更新课程的总分、平时成绩和考试成绩等属性。
  • 对学生数组按学号进行排序。
  • 对班级数组按班号进行排序。
  • 对课程数组按名称的首字母进行排序。
  • 遍历班级数组,输出班级信息及班级内每个学生的成绩情况。 

由于该题难度很高,故我所写的代码中依然存在一些bug。我还需要对程序不断的进行断点调试,以消除bug。

虽然没能将该题完全做出来,但我还是学习到了很多。在Java中,创建一个庞大的系统首先需要创建各类对象,理清各类对象之间的联系和逻辑以及操作,随后将各类对象串联起来。

踩坑心得

类的操作中,最大的坑就是类数组的创建。

在“菜单计价系统”这一题中,我需要在订单类中创建一个记录菜单类数组,我首先想到的便是直接在主程序中调用这个类的属性类,声明数组并给它分配空间。

例如该句:

Order ord = new Order();
Record[] ord.records = new Record[10];

 

但是在编译软件中,该句报出以下错误:

Navigate to previous declared variable 'ord'

Create local variable 'records'

Create field 'records' in 'Main'

Create parameter 'records'

Rename reference

我查询资料后得知,属性类的数组的创建,不能在主程序中分配空间,应该在属性类所在的类中分配空间,因为Java是对类进行操作。

因此,上述操作应该放在Order类里,修改如下:

public static class Order {
        Record[] records = new Record[10];
……
}

也可修改为无参构造:

        public Order() {
            menu = new Menu();
            Record[] records = new Record[10];
        }

还可以修改为有参构造:

        public Order(int n) {
            menu = new Menu();
            Record[] records = new Record[n];
        }

 

属性类数组的创建就如上述操作。

我个人认为这是我学习Java以来遇到的最大的坑,为此我查阅了不少资料,希望读者能够在我的经验总结之下避免再踩这个坑。

总结

经过了三次题目的学习,我已经熟练掌握了Java编程,熟悉了各类的操作方法和类之间的关联,如日期类的基本运用,字符串的基本操作和属性类数组的创建等。

我认为我还需要加强对类的联系运用,并且对于各类之间的逻辑分析还需要深入研究,掌握类图的运用和加强对代码的简化。