pta三次实验的总结
第一次pta作业
在pta第一次作业,因为是第一次作业所以大体是比较容易,但是也有几个要注意的点,就是两个double的值相加减相乘的值与实际值会有一定的误差,误差大小为0.0000001,所以在写pta的三角形的判断类型的时候会有等腰三角形测试答案错误,不能通过测试点,但是在测试直角三角形时用直角三角形的常用判断定理测试点可以通过。
输入三角形三条边,判断该三角形为什么类型的三角形。
输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[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”。
如图
所以我修该判断代码
if(a==b||a==c||b==c)
if(b*b+c*c-a*a<0.1||a*a+c*c-b*b<0.1||a*a+b*b-c*c<0.1)
System.out.print("Isosceles right-angled triangle");后:
代码如下:
1 import java.util.Scanner; 2 public class Main 3 { 4 public static void main(String[] args) 5 { 6 Scanner input = new Scanner(System.in); 7 double a = input.nextDouble(); 8 double b = input.nextDouble(); 9 double c = input.nextDouble(); 10 if(a<1||a>200||b<1||b>200||c<1||c>200) 11 System.out.print("Wrong Format"); 12 else if(a+b<=c||a+c<=b||c+b<=a) 13 System.out.print("Not a triangle"); 14 else if(a==b&&a==c&&b==c) 15 System.out.print("Equilateral triangle"); 16 else if(a*a==b*b+c*c||b*b==a*a+c*c||c*c==a*a+b*b) 17 System.out.print("Right-angled triangle"); 18 else if(a==b||a==c||b==c) 19 if(b*b+c*c-a*a<0.1||a*a+c*c-b*b<0.1||a*a+b*b-c*c<0.1) 20 System.out.print("Isosceles right-angled triangle"); 21 else 22 System.out.print("Isosceles triangle"); 23 else 24 System.out.print("General triangle"); 25 return; 26 } 27 }
第二次pta作业
在第二次pta作业中,我认为比第一次要难一点,但是也不是太难,主要时要我们熟悉和会运用类,以及了解类与类之间的关系,以及关于类的封装,比如在7-1题中,主要是设计一个学生类,类中需要含有学生的姓名、学号、三科成绩的得分,但是我还加入了一个计算总分的属性,从而使在输出时,直接除以3就是该同学的平均分。
创建学生类,包含
属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)
方法:计算总分、计算平均分
输入5个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
代码如下:
1 import java.util.Scanner; 2 class Student 3 { 4 String idnum; 5 String name; 6 int Language; 7 int math; 8 int physics; 9 int sum; 10 } 11 public class Main 12 { 13 public static void main(String[] arg) 14 { 15 int i; 16 Scanner input = new Scanner(System.in); 17 Student[] stu = new Student[5]; 18 for(i = 0;i < 5;i ++) 19 { 20 stu[i] =new Student() ; 21 stu[i].idnum = input.next(); 22 stu[i].name = input.next(); 23 stu[i].Language = input.nextInt(); 24 stu[i].math = input.nextInt(); 25 stu[i].physics = input.nextInt(); 26 stu[i].sum += (stu[i].Language + stu[i].math + 27 stu[i].physics ); 28 double average = (double)stu[i].sum / 3; 29 System.out.print(stu[i].idnum+" "+stu[i].name+" "+ 30 stu[i].sum+" "+ 31 String.format("%.2f", average)); 32 System.out.print("\n"); 33 34 } 35 } 36 37 }
在7-2题成绩计算-2-关联类中,
创建成绩类,包含:
属性:平时成绩(int)、期末成绩(int)
方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)
创建学生类,包含:
属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)
方法:计算总分、计算平均分
输入3个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
所以我设计的类是,Student类包含有Score类如图所示
还有就是这个题,其他的都与题干给的测例一样,但是有一个巨坑的点就是,你不能直接把算好的最后的平均分不能直接输出,因为输出的时候会有精度问题,比如我用的就是double类型,结果在输出的时候,会有精度不准确而导致答案错误,就算解决了题干给的测例,其他的测试点也是不能通过的,如图所示:
所以我在那傻傻的一直调试后,发现只要先算出总分,再用总分除以三,就是与测例一摸一样,就可以过了,但是需要很多类型转换,如下
System.out.println(String.format("%.2f", ((double)((int)stu[i].getScore())/3)));
实验结果如下:
代码如下:
1 import java.util.Scanner; 2 3 class Student 4 { 5 private String idn; 6 protected String nam; 7 private Score subjcet = new Score(); 8 private double sumnor; 9 private double sumfin; 10 private double average =0; 11 class Score { 12 private int Nor; 13 private int Fin; 14 public void setNor(int nor,int fin) 15 { 16 this.Nor =nor; 17 this.Fin = fin; 18 } 19 public int getNor() { 20 return Nor; 21 } 22 public int getFin() { 23 return Fin; 24 } 25 26 } 27 public String getname() { 28 return nam; 29 } 30 public void setname(String name) 31 { 32 this.nam = name; 33 } 34 public void setIdnum (String idnum ) 35 { 36 this.idn = idnum ; 37 } 38 public String getidnum() { 39 return idn; 40 } 41 void setScore (int nor,int fin) { 42 this.subjcet.setNor(nor,fin); 43 this.sumnor += nor; 44 this.sumfin += fin; 45 int m = (int)average; 46 average = m+nor*0.4+fin*0.6; 47 } 48 double setSumnor(){ 49 double b = sumnor /3; 50 return b; 51 } 52 double setSumfin(){ 53 double a = this.sumfin /3; 54 return a; 55 } 56 public double getScore() { 57 return average; 58 } 59 } 60 public class Main 61 { 62 public static void main(String[] arg) 63 { 64 int i; 65 Scanner input = new Scanner(System.in); 66 Student[] stu = new Student[3]; 67 stu[0] =new Student(); 68 stu[1] = new Student(); 69 stu[2] = new Student(); 70 for(i = 0;i < 9;i ++) 71 { 72 String id = input.next(); 73 String name = input.next(); 74 String subject = input.next(); 75 int socre1 = input.nextInt(); 76 int score2 = input.nextInt(); 77 //if(subject.equals("")) 78 79 if(i<3) 80 { 81 82 stu[0].setname(name) ; 83 stu[0].setIdnum(id) ; 84 stu[0].setScore(socre1,score2); 85 } 86 else if(i>=3&&i<6){ 87 88 stu[1].setname(name) ; 89 stu[1].setIdnum(id) ; 90 stu[1].setScore(socre1,score2); 91 // stu[1].getScore(); 92 } 93 else{ 94 95 stu[2].setname(name) ; 96 stu[2].setIdnum(id) ; 97 stu[2].setScore(socre1,score2); 98 // stu[2].getScore(); 99 } 100 } 101 int j; 102 for(i=0;i<3;i++){ 103 System.out.print(stu[i].getidnum()+" "+stu[i].getname()+" "+(int)(stu[i].getScore()) ); 104 System.out.print(" "+String.format("%.2f", stu[i].setSumnor()) +" "); 105 System.out.print(String.format("%.2f", stu[i].setSumfin()) +" "); 106 System.out.println(String.format("%.2f", ((double)((int)stu[i].getScore())/3))); 107 108 } 109 } 110 111 }
我认为在不了解类与类之间的关系时,做7-7菜单菜单计价程序-1时,是比较难的,当然这道题也可以不用类去写,但是我认为既然学了Java还是应该用类写,不然学了Java但是没有学到java的魂,还不如用C语言写。
某饭店提供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)
//添加一条菜品信息到订单中。
}
我认为这几个类是互有联系的,可以在一个类里面包含其他类,也可以分开为几个类,所以我一度纠结,但是后来我选择了后者,建立相应的类如图所示:
当然在代码运行时,会有问题出现就是会有数组输出的时候为“null”导致出了错误,经过上网查阅相应的资料和一系列的改动,最终解决了该问题,就是在应用类的数组时,每使用一个接需要给一个新的类,或者这个类你已经在子类里赋予过了,才能把值赋予到数组里面。idea时如图所示:
还有一个坑就是,对于除不断的时候,就需要我们去判断他的小数点后面的值比0.5大还是比0.5小,小于0.5去掉小数部分,大于0.5整数部分加1;在这里我们只需要去判断单价除2后是否存在余数,有余数不为0当然就是加一,为0时只要整数部分;如代码
if(unit_price%2==0)
uni_price = (int)(unit_price*1.5);
else
uni_price = (int)(unit_price*1.5)+1;
没修改代码之前:
金he
当然我的代码还是有一定的缺陷,比如很好的不能输出菜名,只是方便了输出最后的统计金额;
我的代码:
import java.util.Scanner; class Dish { String name; int unit_price; int getPrice(int portion) { int uni_price =0; if (portion == 1) uni_price = unit_price; if(portion==2){ if(unit_price%2==0) uni_price = (int)(unit_price*1.5); else uni_price = (int)(unit_price*1.5)+1; } if(portion ==3) uni_price = unit_price*2; return uni_price; } } class Record { Dish d = new Dish() ;//菜品 int portion;//份额(1/2/3代表小/中/大份) int getPrice()//计价,计算本条记录的价格 { d = new Dish() ; int price = d.getPrice(portion); return price; } } class Menu { Dish[] dishs /=new Dish[100]; Dish searthDish(String dishName) { int i = 5; if (dishName.equals("西红柿炒蛋") ) { dishs[0] = new Dish() ; dishs[0].name = "西红柿炒蛋"; dishs[0].unit_price = 15; i = 0; } else if (dishName.equals("清炒土豆丝")) { dishs[1] = new Dish() ; dishs[1].name = "清炒土豆丝"; dishs[1].unit_price = 12; i = 1; } else if (dishName.equals("麻婆豆腐") ) { dishs[2] = new Dish() ; dishs[2].name = "麻婆豆腐 "; dishs[2].unit_price = 12; // System.out.println(dishName); i = 2; } else if (dishName.equals("油淋生菜")) { dishs[3] = new Dish() ; dishs[3].name = "油淋生菜"; dishs[3].unit_price = 9; i = 3; } else { dishs[i] = new Dish() ; dishs[i].name = dishName; dishs[i].unit_price = 0; System.out.println(dishs[i].name + " " + "does not exist"); } return dishs[i]; } } class Order { Record[] records = new Record[100] ;//保存订单上每一道的记录 int k;//第几道菜 int getTotalPrice()//计算订单的总价 { int sum = 0; sum += records[k].getPrice(); return sum; } Record addARecord(String dishName, int portion) { //添加一条菜品信息到订单中。 records[k] = new Record() ; records[k].d = new Dish() ; records[k].d.name = dishName; records[k].portion = portion; // System.out.print(dishName+" "+k); return records[k]; } } public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); int i=0,sum=0; Order order = new Order() ; Menu menu =new Menu(); int na = 0; String name1; // String k = "end"; while(na!=1){ name1 = input.next(); if(name1.equals("end")) break; int num = input.nextInt(); order.k = i; order.records[i] = order.addARecord(name1,num); order.records[i].d = menu.searthDish(order.records[i].d.name ); sum += order.records[i].d.getPrice(num); i++; } System.out.print(sum); } }
在7-8 jmu-java-日期类的基本使用,我写的比较复杂,后来我发现可以多次使用库函数就可以解决该问题,比如DateTimeFormatter
和LocalDate
类来处理日期格式和范围的判断。这些类提供了更简洁、安全和可读性更好的方法来处理日期。改进后的代码不再使用正则表达式进行日期格式的验证,而是直接使用提供的日期格式解析字符串。如果解析失败(例如,日期格式不正确),将抛出DateTimeParseException
异常,并返回false
。在isValidRange
方法中,我将日期的范围判断直接从java.util.Calendar
改为使用LocalDate
的方法。LocalDate
类提供了获取年份的便捷方法getYear()
,可以直接获取日期对象的年份。
第三次pta作业
在第三次pta作业中,虽然只有四道题,但是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)成绩平均分只取整数部分,小数部分丢弃
参考类图:
设计的类如图所示:
27个测试点,我的最初的代码能通过的测试点如图所示
参考大佬代码后,做了一定的修改尤其是对student信息的输出时,在输出也有报错,以下代码是以id的后面两位为基础进行排序同时学生信息也跟着排序:
int j,t; int[] arr3 = new int[listCourse.size()+1] ; Course[] cou2 = new Course[listCourse.size() +2] ; for(j=0;j<listCourse.size() ;j++){ Course course=listCourse.get(j); cou2[j] = new Course() ; cou2[j] = course; ArrayList<ChooseCourse> stuCourseSelects=getCourseSelects(course.getCourseName()); if(stuCourseSelects.size()!=0){ if(course.getFlag() ==1) arr3[j] = getAvgTotalScore(stuCourseSelects ) ; if(course.getFlag() == 0) arr3[j] = getAvgTotalScore(stuCourseSelects ) ; } else { arr3[j] = -1; } } for(j=0;j<listCourse.size() ;j++){ for(t=j+1;t<listClass .size() ;t++) { if (arr3[j] != -1 || arr3[j + 1] != -1) { if (arr3[j] > arr3[t]) { int tem = arr3[j]; arr3[j] = arr3[t]; arr3[t] = tem; Course cou3 = new Course(); cou3 = cou2[j]; cou2[j] = cou2[t]; cou2[t] = cou3; } } } }
后来想了想除了后面的id号码,还有班级一样为前提,忽略了班级也是排序的一大重要部分(最重要的部分),比如两个不同班级的两个人20144510和20144609的学号,正常的来说应该输出4510的学生信息,但是经过该排序后输出的是4609的学生信息,所以导致答案错误如图所示
还有一个小坑就是在过单科一个人的时候,有个测试点是在单科成绩为零的时候,输出依旧是正确的而不是带错误提示的,如果以成绩为零,为判断标准时,这个测试点就不能通过,需要重新去定义判断条件,我的建议是,要么对类里面的值赋值为-1或者对有成绩的学生进行flag标记,那么判断条件可以不改变,测试点应该可以通过还有一个就是进行空的判断。
后来利用arrylist数组的特性,使用集合的工具类Collections
进行降序排序,当然在进行降序排序的时候,需要了解一部分arrylist的特性
方法 | 描述 |
add() | 将元素插入到指定位置的 arraylist 中 |
addAll() | 添加集合中的所有元素到 arraylist 中 |
clear() | 删除 arraylist 中的所有元素 |
sort() | 对 arraylist 元素进行排序 |
contains() | 判断元素是否在 arraylist |
get() | 通过索引值获取 arraylist 中的元素 |
indexOf() | 返回 arraylist 中元素的索引值 |
removeAll() | 删除存在于指定集合中的 arraylist 里的所有元素 |
size() | 返回 arraylist 里元素数量 |
完整代码:
import java.text.Collator; import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); ParseInput handle=new ParseInput(); int na = 1; while (na==1) { String line = input.nextLine() ; if(line.equals("end") ) break; handle.parseInput(line);//解析用户输入的每一行数据 } handle.showStudents(); handle.showCourses(); handle.showClasses(); } } class ParseInput{ ArrayList <Student> listStudent=new ArrayList<>(); List<Course> listCourse=new ArrayList<>(); List<Class> listClass=new ArrayList<>(); List<ChooseCourse> listChooseCourse=new ArrayList<>(); public void parseInput(String str){ InputMat mat=new InputMat(); int flag=mat.matchingInput(str); switch (flag){ case 0:System.out.println("wrong format"); break; //课程信息 case 1:{ String letters[]=str.split(" "); String coName=letters[0];//课程名 String type=letters[1];//课程类型 String testType=letters[2];//课程考试类型 Course course = new Course() ; course.courseName = coName ; course.type = type ; course.testType = testType ; if(checkCourse(course)){ if(searchCourse(coName)==null) listCourse.add(course); } break; } //成绩信息 case 2: { 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(); cla.classId = classID ; listClass.add(cla); } Student stu = new Student() ; stu.id = stuId ; stu.clsId = classID ; stu.stuName = 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); course.flag = 0; 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); course.flag =1; ChooseCourse chooseCourse=new ChooseCourse(course,stu,examGrade); listChooseCourse.add(chooseCourse); } else{ //学号+英文空格+姓名+英文空格+": access mode mismatch" System.out.println(stuId+" "+name+" "+": access mode mismatch"); } } break; } } } public boolean checkCourse(Course course){ int flag1,flag2; if(course.getType().equals("必修") ){ flag1 = 0; } else if(course.getType().equals("选修") ){ flag1 = 1; } else { flag1 = 2; } if(course.getTestType() .equals("考试") ){ flag2 = 0; } else if(course.getTestType() .equals("考察") ){ flag2 = 1; } else { flag2 = 2; } 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); int j,t; int[] arr1 = new int[listStudent.size()+2]; Student[] stu3 = new Student[listStudent.size() ] ; for(j=0;j<listStudent.size() ;j++){ Student stu1 = listStudent.get(j); String a = stu1.id.substring(6,8) ; arr1[j]= Integer.parseInt(a) ; stu3[j] = new Student() ; stu3[j] = stu1; } for(int i=0;i<listStudent.size();i++){ Student stu=stu3[i];//listStudent.get(i); //从总选课表listChooseCourse中获取该生的选课记录 ArrayList<ChooseCourse> stuCourseSelects=getStudentSelects(stu.getId()); if(stuCourseSelects.size()==0) { System.out.print(stu.getId()+" "+stu.getStuName()+" "); System.out.println("did not take any exams"); } else { System.out.print(stu.getId()+" "+stu.getStuName()); System.out.println(" "+getAvgTotalScore(stuCourseSelects)); } } } public void showCourses(){ Collections.sort(listCourse); int j,t; int[] arr3 = new int[listCourse.size()+1] ; Course[] cou2 = new Course[listCourse.size() +2] ; for(j=0;j<listCourse.size() ;j++){ Course course=listCourse.get(j); cou2[j] = new Course() ; cou2[j] = course; ArrayList<ChooseCourse> stuCourseSelects=getCourseSelects(course.getCourseName()); if(stuCourseSelects.size()!=0){ if(course.getFlag() ==1) arr3[j] = getAvgTotalScore(stuCourseSelects ) ; if(course.getFlag() == 0) arr3[j] = getAvgTotalScore(stuCourseSelects ) ; } else { arr3[j] = -1; } } for(j=0;j<listCourse.size() ;j++){ for(t=j+1;t<listClass .size() ;t++) { if (arr3[j] != -1 || arr3[j + 1] != -1) { if (arr3[j] > arr3[t]) { int tem = arr3[j]; arr3[j] = arr3[t]; arr3[t] = tem; Course cou3 = new Course(); cou3 = cou2[j]; cou2[j] = cou2[t]; cou2[t] = cou3; } } } } 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.getFlag() ==1) System.out.println(course.getCourseName()+" "+getAvgUsualScore(stuCourseSelects)+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects)); if(course.getFlag() == 0) System.out.println(course.getCourseName()+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects)); } else { System.out.println(course.courseName+" "+"has no grades yet"); } } } public void showClasses(){ Collections.sort(listClass); int j,t; int[] arr2 = new int[listClass.size() +1] ; Class[] cla1 = new Class[listClass.size() ] ; for(j=0;j<listClass.size() ;j++){ Class clasd1 =new Class() ; clasd1 = listClass.get(j); arr2[j] = Integer.parseInt(clasd1.getClassId() )-Integer .parseInt(listClass.get(0).getClassId()) ; cla1[j] = new Class() ; cla1[j] = clasd1 ; } for(j=0;j<listClass.size() ;j++){ for(t=j+1;t<listClass.size();t++){ if(arr2[j]>arr2[t]){ int temp = arr2[j]; arr2[j] = arr2[t]; arr2[t] = arr2[j]; Class clasd2 = cla1[j]; cla1[j] = cla1[t]; cla1[t] = clasd2 ; } } } for(int i=0;i<listClass.size();i++){ Class cls=cla1[i]; ArrayList<ChooseCourse> stuCourseSelects=getClassSelects(cls.getClassId()); if(stuCourseSelects.size()==0){ System.out.print(cls.getClassId()+" "); System.out.println("has no grades yet"); } else { System.out.print(cls.getClassId()+" "); System.out.println(getAvgTotalScore(stuCourseSelects)); } } } 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 getAvgTotalScore(ArrayList<ChooseCourse> cs){ int average=0; int sum=0; for(ChooseCourse c:cs){ sum+=c.grade.getTotalGrade(); } average=sum/cs.size(); return average; } public int getAvgUsualScore(ArrayList<ChooseCourse> cs){ int average=0; int sum=0; for(ChooseCourse c:cs){ if(c.course.getFlag() == 1){ sum+=c.grade.getUsualGrade(); } } average=sum/cs.size(); return average; } 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; int flag; 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 int compareTo(Student stu){ int id = getId().compareTo(stu.getId()); return id; } } class Course implements Comparable<Course>{ String courseName; String type; String testType; int flag; public Course() { } public String getCourseName(){ return courseName; } public String getType(){ return type; } public String getTestType(){ return testType; } public int getFlag (){ return flag; } public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); int coursename = compare.compare(courseName,o.getCourseName()); return coursename ; } } class Class implements Comparable<Class>{ String classId; public Class() { } public String getClassId(){ return classId; } public int compareTo(Class o) { int claid = getClassId().compareTo(o.getClassId()); return claid; } } 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 getTotalGrade(){ int total = (int)(usualGrade*0.3+finalGrade*0.7); return total; } } class AssessGrade extends Grade{ public AssessGrade(int finalGrade) { this.finalGrade=finalGrade; } public int getFinalGrade(){ return finalGrade; } public int getUsualGrade() { return 0; } public int getTotalGrade(){ return finalGrade; } } class InputMat { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修)"; static String checkCourseTypeMatching = "(考试|考察)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ; static String scoreInput2= stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " +scoreMatching; public InputMat() { } 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; } }
总结:
在这三次pta实验作业中我从一个小白,开始慢慢地了解到了,Java的容易到复杂是那么的快,以及让我印象比较深的是库函数的应用,可以大大减少代码量,使代码简洁明了,还有就是在写Java的时候,我们不要太心急写类,我们应该想想这样写类是比较好的,一个好的类,可以大大的减少代码量和思考问题的方式,我在这三次实验里,感觉最深刻的是,类与类的相互联系,比如第三次实验的7-2以及菜单实验,都提示了类的作用。还用就是对arrylist数组有了一定的理解和应用,我相信他会对以后的实验有很强的作用,尤其是数组的增删改查。还有就是对类的继承也开始有一定的理解。类的继承更是有利于代码的书写。我也开始被慢慢的磨练自己的性情,因为在学c的时候写pta最长不会超过一百行代码,一旦超过我就不想写,现在java随随便便就超过百行,有时候写的代码长度比C语言课设差不多,而且pta对代码长度有一定的要求,就比如在写实验3的时候7-2就有几次代码超过了长度,导致连pta都不运行。同时我也在这几次实验中获得的了,好多有用的东西,比如哈希表等之类的知识。