面向对象程序编程PTA题目集4、5以及期中考试的总结性Blog
1.对之前发布的PTA题目集4、5以及期中考试的总结性Blog
(1)前言:总结之前所涉及到的知识点、题量、难度等情况
期中考试作业:
知识点:主要就是考了对类的使用,和不同类间的相互配合使用,还有对于一个程序的不断循环使用(相比之前更加灵活,可以自定义输入的个数),正则表达(可用可不用,这里可以用正则表达式来区别对正方形和圆型的输入,但是没必要,没有什么合法性判断,直接用If就可以平替)
题量与难度:这次期中考试的题量就三题,算是较少了,而且难度相对于之前写的菜单作业真的是一个天上一个地下,相比之下,真的是非常简单了,而且一下子就可以写完,熟练一点,估计也就30分钟作业的题量
PTA第四次题目集作业:
知识点:也就是正则表达式了,主要就算对正则表达式的更改,但是正则表达式的匹配是真的写起来难受,所以思路是有,但是还是得多次调试正则表达式才能达到目的。除此之外,还要改一些其他的阿部分。
难度与题量:更麻烦。因为多了个考点,对代码运行时间的把控,对代码占内存的把控。难了很多,花了很多时间,两天时间一天到晚都在写,最后只拿了个64分。最难点的地方就在对代码运行时间和内存的把控(这个坑,我放到踩坑心得细讲),我前几次提交基本所有测试点都超时了,写是写对了,但是超时了,一分也没有,难就难在不仅要更新,还需要把此前的代码每个地方都要换成运行更快的代码,比如加强循环改成迭代器,少用循环等等
PTA第五次题目集作业:
知识点:此次PTA题目仅只有这一个题目,在菜单三的基础上新增了口味选项,特色菜的相关选项,主要考的内容就是对类的使用(类似现实,对有关联的各个数据合并在一起,便于一起使用),运用正则表达式(比较苦难使用,要记住那些符号对应那些匹配,而且匹配的机制非常严格,常常想要达到预期的匹配效果需要经过很多次的调试,常用于对输入数据的合法性判断,难用,但是也非常实用),数组列表,对数组列表的接口类Comparable(在对数组列表中的内容的排序非常方便,而且内部的CompareTo可以自行定义升序降序或者其他的排序方法,常用好用),还有对字符串的分割(sqilt),对字符串的部分截取(subString),对输入的数据 的解析(根据输入的一行数据,来判断这行数据大体要干嘛,然后调用特定的方法来对这串字符串进行解析),比较字符串(equals,这个与==的比较方法就完全不同,==可以用来比较基本类型的值,也可以用来比较引用类型的地址值;equals则不能用来比较基本类型的值,可以比较引用类型的地址值,相对的可以在需要的类中重写equals方法,使得可以比较对象中的特定内容,例如String类就可以比较不同类中的字符串内容了),控制输出的格式(String.format("%d",12345);和与c语言格式化输出大同小异的system.out.printf(""),这个主要是用于控制一些小数的精确程度),对实际问题的合法性判断(在PTA里这个要先判断,不行要立即return,不能用if-else放到后边else里判断,不然测试点是通过不了的,其他的放到踩坑心得里说)
难度与题量:对代码运行时间的把控,对代码占内存的把控。难度还是挺大的,相对于题目四。题量也就只有一题,但是比较难。
(2)设计与分析:
第四次PTA题目:
7-1 菜单计价程序-4:
设计与解释:大体的思路
分析:根据需求,与菜单三的相似但不完全相同,除了Main类外还设计4个类:Dish(菜)类:保存菜信息,Menu(菜单)类:用于保存多个菜谱信息和查找有无此菜,Record(点菜记录)类:记录一次点菜中的菜信息和份额和个数和序号,Order(点单)类;保存此客户的所有订单信息并算出总价。Dish类有:name 姓名,unit_price单价,getPrice(int portion)计算此份额的价格。Menu类有:dishes多个菜品, searchDish(String dishName)查找菜单中有无此菜,addDish(String dishName, int unit_price)添加菜到菜单。Record类有:dish记录这个菜,portion记录这个菜的份额,ordernum记录订单序号,getPrice()计算此菜的价格。Order类有:records 保存用户的所有点菜记录,addARecord(String dishName, int portion)添加订单,getTotalPrice()计算总价格,find(int ordernum) 根据序号查找一条记录,delet(int ordernum) 根据序号删除一条记录,在以上框架写完后,再补充进去此次菜单四需要的更多异常数据的判断



分析与心得:相比于菜单三,这次题目就心添加了几个异常处理,主要就算对正则表达式的更改,但是正则表达式的匹配是真的写起来难受,所以思路是有,但是还是得多次调试正则表达式才能达到目的。除此之外,还要改一些其他的阿部分。
第五次PTA题目集:
设计与解释:大体的思路
根据需求,本题和菜单计价程序-4同属菜单计价程序-3的两个不同迭代分支。菜单三的基础上新增了口味选项,特色菜的相关选项



分析:与菜单四的相似但不完全相同,除了Main类外还设计4个类:Dish(菜)类:保存菜信息,Menu(菜单)类:用于保存多个菜谱信息和查找有无此菜,Record(点菜记录)类:记录一次点菜中的菜信息和份额和个数和序号,Order(点单)类;保存此客户的所有订单信息并算出总价。Dish类有:name 姓名,unit_price单价,getPrice(int portion)计算此份额的价格。Menu类有:dishes多个菜品, searchDish(String dishName)查找菜单中有无此菜,addDish(String dishName, int unit_price)添加菜到菜单。Record类有:dish记录这个菜,portion记录这个菜的份额,ordernum记录订单序号,getPrice()计算此菜的价格。Order类有:records 保存用户的所有点菜记录,addARecord(String dishName, int portion)添加订单,getTotalPrice()计算总价格,find(int ordernum) 根据序号查找一条记录,delet(int ordernum) 根据序号删除一条记录,在以上框架写完后,再补充进去在菜单三的基础上新增了口味选项,特色菜的相关选项
心得:相比于菜单三,这次题目就心添加了新增了口味选项,特色菜的相关选项
期中考试题目集:
此次题目集较为简单,就不过多赘述,大体的说一下就行
设计与解释:大体的思路
题目一:圆形的设计
设计与解释:大概就是创建一个关于圆形的类就行,在当中加入圆形的半径和面积的数据就行,
然后再加上一个计算面积的方法,getArea
题目二:对正方形的设计
设计与解释: 大概就是创建个父类,然后加上图像特有的坐标作为数据,根据坐标做一个Getarea方法就行,
题目三:7-3 测验3-继承与多态
设计与解释:大体的思路对圆形,正方形,的面积计算的多次循环

分析:多态的好处在于可以提高代码的灵活性和扩展性。通过使用父类引用,我们可以写出更通用的,当需要增加新的子类时,无需修改已有的代码,只需要向现有的继承体系中添加新的子类即可。继承(Inheritance)是指一个类(子类)可以从另一个类(父类)继承其属性和方法。子类可以通过继承来复用父类的代码,并且可以在其中添加新的功能或修改现有功能。在Java中,使用关键字"extends"来表示继承关系
心得:继承和多态是Java程序设计的重要特性,它们能够有效地组织和管理复杂的代码结构,并使代码具有更高的可重用性和可扩展性
分析与心得:没啥分析,就算个While的循环,然后按情况分别调用正方形和圆形
题目四:7-4 测验4-抽象类与接口
设计与解释:实现Comparable接口,然后重写比较的方法,再代码中就可以使用Collections.sort的方法快速排序了
(3)采坑心得:
1.对于实际问题的合法性判断:这个是我在PTA遇到的第一个百思不得其解的坑,也是偶然中发现的,先单纯说在作业上:对于有关于合法性判断的测试点,必须得将合法性判断置于代码的最上边位置,不合格则立即return退出程序或者跳过一段程序。如果将合法判断置于后面,比如if-else放在else后面,即使最后运行结果一样,但是这个测试点就是不通过。总结就是在运行某段代码前,先判断是否合法,合法则执行这段代码,不合法则不执行这段代码直接跳过。然后在代码上的理解:我认为这样的好处是可以使代码运行的更快,因为当不合格时便不会读取其他多余的代码。
2.对代码运行时间和内存的把控:在PTA里面写这种系列更新题目的后期最大难题,你会是会写,但是你不会要会写,你还要智写,不能随便叠代码来完成,得用一些更高级的代码来替代那些简单代码以来减少运行时间。不仅是这次成绩管理系统,包括上次的菜单系统,越更新到后面,就越容易测试点超时。不能总是用循环来干事,得多换成迭代器,多用继承和组合加强代码复用
3.排序:先对长度排序,再在同长里面调用compareToIgnoreCase()方法。因为compareToIgnoreCase()函数在队不同长度的单词进行排序时会出现排不准的情况。还有也不能用compareTo()方法,这个方法会考虑单词的大小写,让排序不准确,题目准确写了忽略大小写,故用compareToIgnoreCase()才是最优解,可以忽略单词的大小写进行比较。
4.快读快写:用快读快写时,一定要记得在方法标签后面+throws IOException,不然是运行不了的。而且在创建对象时的代码是很长的,不好记而且容易打错,所以建议把创建对象的代码复制到一个常用代码文档里,要用的时候就不用再打一遍了。
(4)改进建议:
1.写代码的时的细节问题和全局思想问题:写代码时总是会遗漏;{}等小细节问题,导致很多时候一运行报错了,到处找错误找不到,费了一番功夫才发现原来是某个小细节问题,同时也归咎于没有养成在报错的时候仔细看Idea给的报错可能,因为是英文所以老是懒得看。全局思想是常常遇到题目就开始写,并没有构思一下
2.数据的重复与排序:有关重复数据和排序的,当时还不知道哈希表,就只能一股脑的用循环嵌套去解决,十分的麻烦,而且经常会测试点超时。比如的数据就可以直接全部add入哈希表中,然后再将删除重复数据的哈希表内个数与原个数比较就行。同理,最后遍历输出就行,可以极大的简化代码。
(5)总结:
知识上:学到了队类的使用,封装,String类,日期类,包装类中的一些方法,哈希表,数组列表,equals与==的不同等
思路上:学到了基本的解题步骤,需求分析,不断分解成子问题,由下向上逐步解决,阶段性调试测试,先构建出基本框架,写出基本功能,检查Bug,最后再来对整体的优化(比如让界面更简洁啊,简化一些代码啊等等)
当然还有很多没有弄明白的方面,还在学习正则表达式和javaFX动画驱动的内容
(6)菜单四的代码附录
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Analyse analyse = new Analyse();
String string1 = in.nextLine();
while (!string1.equals("end"))
{
analyse.stringAnalyse(string1);
string1= in.nextLine();
}
analyse.showError();
analyse.showStu();
analyse.showCourse();
analyse.showCla();
}
}
class Student implements Comparable<Student>{
String name;
String num;
int average;
ArrayList<Select> selects = new ArrayList<Select>();
Student(String name,String num)
{
this.name = name;
this.num=num;
}
public Select addSelect(Select select)
{
selects.add(select);
return select;
}
public void sumAverage()
{
int total = 0;
for(Select temp:selects)
{
total = total+temp.score.totalScore;
}
if(selects.size()==0)
return;
this.average=total/(selects.size());
}
@Override
public int compareTo(Student o) {
return this.num.compareTo(o.num);
}
}
class Cla implements Comparable<Cla>{
String num;
ArrayList<Student> students = new ArrayList<Student>();
int classAverage;
Cla(String num)
{
this.num=num;
}
public Student addStudent(Student student)
{
students.add(student);
return student;
}
public void sumAverage()
{
int total = 0;
for(Student temp:students)
{
total = total+temp.average;
}
if(students.size()==0)
return;
this.classAverage=total/(students.size()); }
@Override
public int compareTo(Cla o) {
return this.num.compareTo(o.num);
}
}
class Course implements Comparable<Course>{
String name;
String type;
String method;
int courseAverage;
int finalaverage;
int usualaverage;
ArrayList<Select> selects = new ArrayList<Select>();
Course(String name,String type,String method)
{
this.name=name;
this.type=type;
this.method=method;
}
public Select addSelect(Select select)
{
selects.add(select);
return select;
}
public void sumAverage()
{
int total = 0;
for(Select temp:selects)
{
total = total+temp.score.totalScore;
}
if(selects.size()==0)
return;
this.courseAverage=total/(selects.size());
}
public void finalaverage()
{
int total = 0;
for(Select temp:selects)
{
total = total+temp.score.finalScore;
}
if(selects.size()==0)
return;
this.finalaverage=total/(selects.size());
}
public void usualaverage()
{
int total = 0;
for(Select temp:selects)
{
total = total+temp.score.usualScore;
}
if(selects.size()==0)
return;
this.usualaverage=total/(selects.size());
}
public int compareTo(Course o) {
Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
return compare.compare(name,o.name);
}
}
class Select {
Course course;
Student student;
Score score;
Select(Course course,Student student,Score score)
{
this.course=course;
this.student=student;
this.score=score;
}
}
abstract class Score {
int totalScore;
int finalScore;
int usualScore;
}
class ExamScore extends Score{
ExamScore(int usualScore,int finalScore)
{
this.usualScore=usualScore;
this.finalScore=finalScore;
this.totalScore=(int)(finalScore*0.7f+usualScore*0.3f);
}
}
class ExploreScore extends Score{
ExploreScore(int finalScore)
{
this.finalScore=finalScore;
this.totalScore=finalScore;
}
}
class Analyse {
ArrayList<Student> students = new ArrayList<>();
ArrayList<Course> courses= new ArrayList<>();
ArrayList<Cla> clas = new ArrayList<>();
ArrayList<Select> selects = new ArrayList<>();
ArrayList<String> errors = new ArrayList<>();
public void stringAnalyse(String string)
{
String[] item = string.split(" ");
if(item.length==3)
{
String name = item[0];
String type = item[1];
String method= item[2];//重复课程的输入混乱,排序重复,未改-对应5异常
Course againCourse = findCourse(name);
if(againCourse!=null)
{
return;
}
if(type.equals("必修"))
{
if(method.equals("考察"))
{
String error = name+" "+": course type & access mode mismatch";
errors.add(error);
//System.out.println(name+": course type & access mode mismatch");
return;
}
Course course = new Course(name,type,method);
courses.add(course);
}
if(type.equals("选修"))
{
Course course = new Course(name,type,method);
courses.add(course);
}
}
if(item.length==4||item.length==5)
{
if(InputMatching.matchingInput(string)==0)//对应异常三,似乎还要一些测试点未达标
{
String error = "wrong format";
errors.add(error);
return;
}
String classNum = item[0].substring(0,6);
String id = item[0];
String stuName = item[1];
Cla cla1= findCla(classNum);
if(cla1==null)
{
cla1 = new Cla(classNum);
clas.add(cla1);
}
Student student1 = findStudent(stuName,id);
if(student1==null)
{
student1= new Student(stuName,id);
students.add(student1);
cla1.addStudent(student1);
}
else //重复学生成绩信息导致同一科目双倍选课,双倍课,双倍人,未改——对应5异常
{
for(Select againselect:student1.selects)
{
if(item[2].equals(againselect.course.name))
{
return;
}
}
}
//int errorSelect = 0;//两处错误报告的优先级,未改;重要-对应2异常
String courseName = item[2];
Course stuCourse = findCourse(courseName);
if(stuCourse==null)
{
String error = courseName+" "+"does not exist";
errors.add(error);
//errorSelect = 1;
return;//次两处错误已经不可能同时出现,但是不排除题目意思是说,即使是不同科目出现两个错误也要选择-待验证-未改
}
if(stuCourse.method.equals("考试"))
{
if(item.length==4)
{
String error = id+" "+stuName+" "+": access mode mismatch";
errors.add(error);
return;
}
int usualScore = Integer.parseInt(item[3]);
int finalScore = Integer.parseInt(item[4]);
Score score = new ExamScore(usualScore,finalScore);
Select select1 = new Select(stuCourse,student1,score);
selects.add(select1);
student1.addSelect(select1);
stuCourse.addSelect(select1);
student1.sumAverage();
stuCourse.sumAverage();
stuCourse.finalaverage();
stuCourse.usualaverage();
cla1.sumAverage();
}
if(stuCourse.method.equals("考察"))
{
if(item.length==5)
{
String error = id+" "+stuName+" "+": access mode mismatch";
errors.add(error);
//System.out.println(id+" "+stuName+" "+": access mode mismatch");
return;
}
int finalScore = Integer.parseInt(item[3]);
Score score = new ExploreScore(finalScore);
Select select1 = new Select(stuCourse,student1,score);
selects.add(select1);
student1.addSelect(select1);
stuCourse.addSelect(select1);
student1.sumAverage();
stuCourse.sumAverage();
stuCourse.finalaverage();
cla1.sumAverage();
}
}
}
public void showError()
{
for (String err:errors)
{
System.out.println(err);
}
}
public void showStu()
{
Collections.sort(students);
for(Student stu:students)
{
if(stu.selects.size()==0)
{
System.out.println(stu.num+" "+stu.name+" "+"did not take any exams");
}
else {
System.out.println(stu.num + " " + stu.name + " " + stu.average);
}
}
}
public void showCourse()
{
Collections.sort(courses);
for(Course cou:courses)
{
if(cou.selects.size()==0)
{
System.out.println(cou.name+" "+"has no grades yet");
}
else {
if (cou.method.equals("考试")) {
System.out.println(cou.name + " " + cou.usualaverage + " " + cou.finalaverage + " " + cou.courseAverage);
}
if (cou.method.equals("考察")) {
System.out.println(cou.name + " " + cou.finalaverage + " " + cou.courseAverage);
}
}
}
}
public void showCla()
{
Collections.sort(clas);
for(Cla cla:clas)
{
if(cla.classAverage==0)
{
System.out.println(cla.num+" "+"has no grades yet");
}
else {
System.out.println(cla.num + " " + cla.classAverage);
}
}
}
public boolean haveCla(String classNum)
{
if(clas.size()==0)
{
return false;
}
for(Cla temp:clas)
{
if(temp.num.equals(classNum))
{
return true;
}
}
return false;
}
public Course findCourse(String courseName)
{
if(courses.size()==0)
{
return null;
}
for(Course temp:courses)
{
if(temp.name.equals(courseName))
{
return temp;
}
}
return null;
}
public Student findStudent(String stuName,String stuNum)
{
if(students.size()==0)
{
return null;
}
for(Student temp:students)
{
if(temp.name.equals(stuName)&&temp.num.equals(stuNum))
{
return temp;
}
}
return null;
}
public Cla findCla(String claNum)
{
if(clas.size()==0)
{
return null;
}
for(Cla temp:clas)
{
if(temp.num.equals(claNum))
{
return temp;
}
}
return null;
}
}
class InputMatching {
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 = "(考试|考察)";
//cousrInput用于定义课程信息模式(正则表达式)
static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
//scoreInput用于定义成绩信息模式(正则表达式)
static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching;
static String secondScoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching + " " + scoreMatching;
public static int matchingInput(String s) {
if (matchingCourse(s)) {
return 1;
}
if (matchingScore(s)||matchSecondScore(s)) {
return 2;
}
return 0;
}
private static boolean matchingCourse(String s) {
return s.matches(courseInput);
}
private static boolean matchingScore(String s) {
//System.out.println(match);
return s.matches(scoreInput);
}
private static boolean matchSecondScore(String s)
{
return s.matches(secondScoreInput);
}
}

浙公网安备 33010602011771号