OOP第一轮PTA作业总结
1. 前言
刚开始学习面向对象程序设计我是信心满满,开始学后我是脚底抽筋!
前三次PTA作业主要是关于类的设计,类的关联,为满足需求对类进行增加和修改;题量不大,在每次作业最后一个大作业前会有两到四个比较简单的小题目,大作业的形式是前一次作业的基础上逐渐增加要求,难度逐渐提升,个人认为是很有挑战度的。
但是本人慵懒笨拙,在第一次PTA作业用老师建议的类设计后,就开始了一个main方法打天下的编程思路,处理过程繁琐,类的设计缺少,最终导致一次作业比前一次作业差劲!
虽然如此,总结还是必然的。
2. 设计与分析
一、第一次PTA作业
(1)题目信息:设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分三部分:
1、题目数量
格式:整数数值,若超过1位最高位不能为0,
样例:34
2、题目内容
一行为一道题,可以输入多行数据。
格式:"#N:"+题号+" "+"#Q:"+题目内容+" "#A:"+标准答案格式约束:题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
样例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
3、答题信息
答题信息按行输入,每一行为一组答案,每组答案包含第2部分所有题目的解题答案,答案的顺序号与题目题号相对应。
格式:"#A:"+答案内容
格式约束:答案数量与第2部分题目的数量相同,答案之间以英文空格分隔。
样例:#A:2 #A:78
2是题号为1的题目的答案
78是题号为2的题目的答案
答题信息以一行"end"标记结束,"end"之后的信息忽略。
输出格式:
1、题目数量
格式:整数数值,若超过1位最高位不能为0,
样例:34
2、答题信息
一行为一道题的答题信息,根据题目的数量输出多行数据。
格式:题目内容+" ~"+答案
样例:1+1=~2
2+2= ~4
3、判题信息
判题信息为一行数据,一条答题记录每个答案的判断结果,答案的先后顺序与题目题号相对应。
格式:判题结果+" "+判题结果
格式约束:
1、判题结果输出只能是true或者false,
2、判题信息的顺序与输入答题信息中的顺序相同
样例:true false true
(2)解答与分析:按照老师给的类设计建议,设计三个类,分别是Problem、Answerpaper和Testpaper。其中类与类的关系用到了关联,其属性和方法以及类间关系如下图。

①Problem类的代码详情:主要存储单个题目信息,属性:题号,题目内容,标准答案;方法包括有参和无参的构造方法,属性的get和set方法。
点击查看代码
class Problem{
private int num;
private String content;
private String answer;
public boolean answerTell(String inanswer){
if(this.answer.equals(inanswer)){
return true;
}else{
return false;
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public Problem(int num, String content, String answer) {
super();
this.num = num;
this.content = content;
this.answer = answer;
}
public Problem(){
}
}
②Testpaper类的代码详情:属性:存储单个试卷的题目数量和Problem类数组,实现与Problem类的关联;方法包括有参和无参的构造方法,属性的get和set方法以及特殊的判断答案啊正确的answerTell方法,返回一个boolean值。
点击查看代码
class Testpaper{
private int problemnumbers=0;
private Problem[] problems=new Problem[100];
public Testpaper(){
}
public Testpaper(int problemnumbers) {
this.problemnumbers = problemnumbers;
}
//存入题目信息
public void setProblems(int num,Problem problem){
this.problems[num-1]=problem;
}
public boolean answerTell(int num,String inanswer){
return problems[num].answerTell(inanswer);
}
public String getProblems(int num){
return problems[num].getContent();
}
}
③Answerpaper类的代码详情:属性:答案信息,答案判断信息,以及Testpaper类,实现了类与类的多重关联;方法包括有参的构造方法,答案判断方法,存储答案信息方法和输出答题结果方法。
点击查看代码
class Answerpaper{
private Testpaper paper=new Testpaper();
private String[] inanswer=new String[100];
private boolean[] judge=new boolean[100];
public boolean getJudge(int num){
return paper.answerTell(num,inanswer[num]);
}
public void putProblem(int num){
System.out.println(paper.getProblems(num)+"~"+inanswer[num]);
}
public void storeAnswer(int num,String answer){
inanswer[num]=answer;
}
public Answerpaper(Testpaper paper, String[] inanswer) {
super();
this.paper = paper;
this.inanswer = inanswer;
}
}
④Main类。该类只有一个main主方法,内初始化对象,实现的功能包括对输入信息的处理存入,判断和最终要求的输出。
方法多为循环处理不做参考。二、第二次PTA作业
(1)题目信息:设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-1基础上增补或者修改的内容。
要求输入题目信息、试卷信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分三种,三种信息可能会打乱顺序混合输入:
1、题目信息
一行为一道题,可输入多行数据(多道题)。
格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
格式约束:
1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。
样例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、试卷信息
一行为一张试卷,可输入多行数据(多张卷)。
格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值
题目编号应与题目信息中的编号对应。
一行信息中可有多项题目编号与分值。
样例:#T:1 3-5 4-8 5-2
3、答卷信息
答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序与试卷信息中的题目顺序相对应。
格式:"#S:"+试卷号+" "+"#A:"+答案内容
格式约束:答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
样例:#S:1 #A:5 #A:22
1是试卷号
5是1号试卷的顺序第1题的题目答案
22是1号试卷的顺序第2题的题目答案
答题信息以一行"end"标记结束,"end"之后的信息忽略。
输出格式:
1、试卷总分警示
该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100分,该部分忽略,不输出。
格式:"alert: full score of test paper"+试卷号+" is not 100 points"
样例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行一道题的答题信息,根据试卷的题目的数量输出多行数据。
格式:题目内容+"~"+答案++"~"+判题结果(true/false)
约束:如果输入的答案信息少于试卷的题目数量,答案的题目要输"answer is null"
样例:3+2=~5~true
4+6=~22~false.
answer is null
3、判分信息
判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。
格式:题目得分+" "+....+题目得分+"~"+总分
格式约束:
1、没有输入答案的题目计0分
2、判题信息的顺序与输入答题信息中的顺序相同
样例:5 8 0~13
根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。
4、提示错误的试卷号
如果答案信息中试卷的编号找不到,则输出”the test paper number does not exist”,参见样例9。
设计建议:
参考答题判题程序-1,建议增加答题类,类的内容以及类之间的关联自行设计。
(2)解答与分析:这次的答题程序要求增加,正确思路应该是增加更多的类,通过多个单一职责原则来实现,但我学艺不精,只能浮于表面只建立原来的三个类;并且这次取消了类的关联,每个类都是独立的。但是额外使用了List和ArrrayList组成对象数组实现更为简便的遍历效果。虽然有所使用新的东西,但是依然是一个main主方法打天下的方法,main方法发中代码繁冗,并且并不是所有测试点都可以通过。类图如下:

①Problem类,同第一次一样属性(题号、题目内容、标准答案)和方法都没有改变。仅仅用来存储题目信息;真的实现了单一职责原则。
点击查看代码
class Problem{
private int num=0;
private String content=null;
private String standardanswer=null;
public int getNum(){
return num;
}
public String getContent(){
return content;
}
public String getStandardanswer(){
return standardanswer;
}
public Problem(){
}
public Problem(int num,String content,String standardanswer){
super();
this.num=num;
this.content=content;
this.standardanswer=standardanswer;
}
}
②Testpaper类:增加属性:试卷编号、题号、题目分数;方法:无参和有参构造方法,三个属性的get方法,以及获取试卷总分的getFull方法。
点击查看代码
class Testpaper{
int testnum=0;
int[] problemnum=new int[10];
int[] problempoints=new int[10];
public int[] getProblemnum(){
return problemnum;
}
public int[] getProblempoint(){
return problempoints;
}
public int getTestnum(){
return testnum;
}
public Testpaper(){
}
public Testpaper(int testnum,int[] problemnum,int[] problempoints){
super();
this.testnum=testnum;
this.problemnum=problemnum;
this.problempoints=problempoints;
}
public void setProblem(){
}
public void putFull(){
int sum=0;
for(int point:problempoints){
sum+=point;
}
if(sum==100){
}else{
System.out.println("alert: full score of test paper"+testnum+" is not 100 points");
}
}
}
③Answerpaper类:增加属性:试卷编号、答题答案、答题得分;方法:无参和有参构造方法,三个属性的get方法,特别增加存储每个题目的得分方法(setPointget)。
点击查看代码
class Answerpaper{
private int answernum=0;
private String[] myanswer=new String[10];
private int[] pointget=new int[10];
public void setPointget(int a,int b){
this.pointget[a]=b;
}
public int[] getPointget(){
return pointget;
}
public String[] getMyanswer(){
return myanswer;
}
public int getAnswernum(){
return answernum;
}
public Answerpaper(){
}
public Answerpaper(int answernum,String[] myanswer){
super();
this.answernum=answernum;
this.myanswer=myanswer;
}
}
④Main类:只有一个main方法来实现题目的输入和输出要求。对三个类进行对象数组,采用List<calss> namelist=new Arraylist<>();的形式存储每一个输入的所有处理过的输入信息。其中计算分数和输出的过程多用while和for循环来便利数组。
点击查看对象类链表形式的初始化
import java.util.List;
import java.util.ArrayList;
List<Problem> problemList=new ArrayList<>();
List<Testpaper> testpaperList=new ArrayList<>();
List<Answerpaper> answerpaperList=new ArrayList<>();
三、第三次PTA作业
(1)题目信息:设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-2基础上增补或者修改的内容,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分五种,信息可能会打乱顺序混合输入。
1、题目信息
题目信息为独行输入,一行为一道题,多道题可分多行输入。
格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
格式约束:
1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。
样例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、试卷信息
试卷信息为独行输入,一行为一张试卷,多张卷可分多行输入数据。
格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值+" "+题目编号+"-"+题目分值+...
格式约束:
题目编号应与题目信息中的编号对应。
一行信息中可有多项题目编号与分值。
样例:#T:1 3-5 4-8 5-2
3、学生信息
学生信息只输入一行,一行中包括所有学生的信息,每个学生的信息包括学号和姓名,格式如下。
格式:"#X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名
格式约束:答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
样例:
#S:1 #A:5 #A:22
1是试卷号
5是1号试卷的顺序第1题的题目答案
4、答卷信息
答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序号与试 卷信息中的题目顺序相对应。答卷中:
格式:"#S:"+试卷号+" "+学号+" "+"#A:"+试卷题目的顺序号+"-"+答案内容+...
格式约束:
答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
答案内容可以为空,即””。
答案内容中如果首尾有多余的空格,应去除后再进行判断。
样例:
#T:1 1-5 3-2 2-5 6-9 4-10 7-3
#S:1 20201103 #A:2-5 #A:6-4
1是试卷号
20201103是学号
2-5中的2是试卷中顺序号,5是试卷第2题的答案,即T中3-2的答案
6-4中的6是试卷中顺序号,4是试卷第6题的答案,即T中7-3的答案
注意:不要混淆顺序号与题号
5、删除题目信息
删除题目信息为独行输入,每一行为一条删除信息,多条删除信息可分多行输入。该信息用于删除一道题目信息,题目被删除之后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示,例如:”the question 2 invalid~0”
格式:"#D:N-"+题目号
格式约束:
题目号与第一项”题目信息”中的题号相对应,不是试卷中的题目顺序号。
本题暂不考虑删除的题号不存在的情况。
样例:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
输出
alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0
答题信息以一行"end"标记结束,"end"之后的信息忽略。
输出格式:
1、试卷总分警示
该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100 分,该部分忽略,不输出。
格式:"alert: full score of test paper"+试卷号+" is not 100 points"
样例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。
格式:题目内容+"~"+答案++"~"+判题结果(true/false)
约束:如果输入的答案信息少于试卷的题目数量,答案的题目要输"answer is null"
样例:
3+2=~5~true
4+6=~22~false.
answer is null
3、判分信息
判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。
格式:**学号+" "+姓名+": "**+题目得分+" "+....+题目得分+"~"+总分
格式约束:
1、没有输入答案的题目、被删除的题目、答案错误的题目计0分
2、判题信息的顺序与输入答题信息中的顺序相同
样例:20201103 Tom: 0 0~0
根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。
4、被删除的题目提示信息
当某题目被试卷引用,同时被删除时,答案中输出提示信息。样例见第5种输入信息“删除题目信息”。
5、题目引用错误提示信息
试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。例如:
输入:
#N:1 #Q:1+1= #A:2
#T:1 3-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-4
end
输出:
alert: full score of test paper1 is not 100 points
non-existent question~0
20201103 Tom: 0~0
如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高,例如:
输入:
#N:1 #Q:1+1= #A:2
#T:1 3-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103
end
输出:
alert: full score of test paper1 is not 100 points
answer is null
20201103 Tom: 0~0
6、格式错误提示信息
输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。
例如:wrong format:2 #Q:2+2= #4
7、试卷号引用错误提示输出
如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”,答卷中的答案不用输出,参见样例8。
8、学号引用错误提示信息
如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。参见样例9。
本题暂不考虑出现多张答卷的信息的情况。
(2)解答与分析:这次程序设计在第二次的基础上有增加多项判题要求,也多出了学生信息与删除题目信息。最为特殊的两个输出条件就是,该题目是被删除的题目信息还是不存在的题目信息。以及多个答卷和多个试卷的处理,让人摸不着头脑。这次的编程设计我依然只设计基础类:Problem、Testpaper、Answerpaper、Student、Delect,在Main类中不仅只有一个main方法了,还有Delectproblem()、testpaperCheck(0、printJudge()方法来减弱main方法的复杂度,使得main主要功能是处理输入的题目、答卷、学生等信息。其中(Testpaper、Answerpaper、Student、Delect)类的属性设计采用ArrayList形式的数组,方便删除、添加和遍历。但仅仅这些设计是完全不够题目要求的,也不符合面向对象设计的整体需求,最后经过不断的修改任然无法满足所有测试点,只能通过部分测试点。
类图如下:

①Problem类,属性不变(题号、题目内容、标准答案),方法包括有参和无参的构造方法,以及属性的set和get方法。
点击查看代码
class Problem {
int problemnum=0;
private String problemcontent=null;
private String standardanswer=null;
public Problem() {
super();
// TODO Auto-generated constructor stub
}
public Problem(int problemnum, String problemcontent, String standardanswer) {
super();
this.problemnum = problemnum;
this.problemcontent = problemcontent;
this.standardanswer = standardanswer;
}
public int getProblemnum() {
return problemnum;
}
public void setProblemnum(int problemnum) {
this.problemnum = problemnum;
}
public String getProblemcontent() {
return problemcontent;
}
public void setProblemcontent(String problemcontent) {
this.problemcontent = problemcontent;
}
public String getStandardanswer() {
return standardanswer;
}
public void setStandardanswer(String standardanswer) {
this.standardanswer = standardanswer;
}
}
②Answerpaper类,属性:试卷编号,学生学号,题号列表,答案列表;方法包括有参和无参的构造方法,属性的get和set方法,对于数组(ArratList)属性特加了add(增加数组)方法。
点击查看代码
class Answerpaper {
private int papernum=0;
private String studentnum=null;
private ArrayList<Integer> problemnumlist;
private ArrayList<String> myAnswerlist;
public Answerpaper(int papernum, String studentnum, ArrayList<Integer> problemnumlist,
ArrayList<String> myAnswerlist) {
super();
this.papernum = papernum;
this.studentnum = studentnum;
this.problemnumlist = problemnumlist;
this.myAnswerlist = myAnswerlist;
}
public Answerpaper() {
super();
// TODO Auto-generated constructor stub
}
public int getPapernum() {
return papernum;
}
public void setPapernum(int papernum) {
this.papernum = papernum;
}
public String getStudentnum() {
return studentnum;
}
public void setStudentnum(String studentnum) {
this.studentnum = studentnum;
}
public ArrayList<Integer> getProblemnumlist() {
return problemnumlist;
}
public void setProblemnumlist(ArrayList<Integer> problemnumlist) {
this.problemnumlist = problemnumlist;
}
public ArrayList<String> getMyAnswerlist() {
return myAnswerlist;
}
public void setMyAnswerlist(ArrayList<String> myAnswerlist) {
this.myAnswerlist = myAnswerlist;
}
}
③Testpaper类,属性:试卷编号,题号列表,题目分数列表,题目标准答案列表;方法包括有参和无参的构造方法,以及属性的get和set方法,同Answerpaper一样,对于数组(ArratList)属性特加了add(增加数组)方法。
点击查看代码
class Testpaper {
private int papernum=0;
private ArrayList<Integer> problemnumlist;
private ArrayList<Integer> problempointslist;
private ArrayList<String> standardanswerlist;
public Testpaper() {
super();
// TODO Auto-generated constructor stub
}
public Testpaper(int papernum, ArrayList<Integer> problemnumlist,
ArrayList<Integer> problempointslist) {
super();
this.papernum = papernum;
this.problemnumlist = problemnumlist;
this.problempointslist = problempointslist;
}
public void addProblemnumlist(int problemnum) {
problemnumlist.add(problemnum);
}
public void addProblempointslist(int problempoints){
problempointslist.add(problempoints);
}
public int getPapernum() {
return papernum;
}
public void setPapernum(int papernum) {
this.papernum = papernum;
}
public ArrayList<Integer> getProblemnumlist() {
return problemnumlist;
}
public void setProblemnumlist(ArrayList<Integer> problemnumlist) {
this.problemnumlist = problemnumlist;
}
public ArrayList<Integer> getProblempointslist() {
return problempointslist;
}
public void setProblempointslist(ArrayList<Integer> problempointslist) {
this.problempointslist = problempointslist;
}
public ArrayList<String> getStandardanswerlist() {
return standardanswerlist;
}
public void setStandardanswerlist(ArrayList<String> standardanswerlist) {
this.standardanswerlist = standardanswerlist;
}
}
④Student类,属性:学号,姓名,得分列表以及总分;方法:无参和有参的构造方法,属性的get和set方法,同样对于数组(ArratList)属性特加了add(增加数组)方法,
点击查看代码
class Student {
private String studentnum=null;
private String studentname=null;
private ArrayList<Integer> pointslist;
private int sumpoints=0;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String studentnum, String studentname) {
super();
this.studentnum = studentnum;
this.studentname = studentname;
}
public void addPointslist(int points) {
pointslist.add(points);
}
public void setSumpoints() {
for(int points:pointslist) {
sumpoints+=points;
}
}
public int getSumpoints() {
return sumpoints;
}
public String getStudentnum() {
return studentnum;
}
public void setStudentnum(String studentnum) {
this.studentnum = studentnum;
}
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
}
public ArrayList<Integer> getPointslist() {
return pointslist;
}
public void setPointslist(ArrayList<Integer> pointslist) {
this.pointslist = pointslist;
}
}
⑤Delect类,属性:需要删除的题目列表;方法:有参和无参的构造犯法,题号的get和set方法。
点击查看代码
class Delect {
private int problemnum=0;
public Delect(int problemnum) {
super();
this.problemnum = problemnum;
}
public Delect() {
super();
// TODO Auto-generated constructor stub
}
public int getProblemnum() {
return problemnum;
}
public void setProblemnum(int problemnum) {
this.problemnum = problemnum;
}
}
④Main类,不光有main主方法,还有Delectproblem()和printJudge()方法为主方法提供方法,使得main方法更加简介,但并没有使得Main类简便,代码冗长复杂,又不能满足要求。
点击查看正则表达式部分内容,匹配器和表达式
import java.util.regex.Pattern;
import java.util.regex.Matcher;
String problemregex="#N:.+#Q:.+#A:.+";
String answerpaperregex="#S:[\\d][\\ss]+[\\d]{8}[\\s]+(#A:[\\d]-[\\w]+[\\s]?)+";
String testpaperregex="#T:[\\d].+";
String studentregex="#X:([\\d]{8}[\\s][\\w]+|[\\d]{8}[\\s][\\w]+-)+";
Pattern problemPattern=Pattern.compile(problemregex);
Pattern answerpaperPattern=Pattern.compile(answerpaperregex);
Pattern testpaperPattern=Pattern.compile(testpaperregex);
Pattern studentPattern=Pattern.compile(studentregex);
String sentence=input.nextLine();
Matcher problemmatcher=problemPattern.matcher(sentence);
Matcher answerpapermatcher=answerpaperPattern.matcher(sentence);
Matcher testpapermatcher=testpaperPattern.matcher(sentence);
Matcher studentmatcher=studentPattern.matcher(sentence);
3. 踩坑心得
(1)第一次PTA作业:
①在类间的关联时,对于属性类的方法调用更加适合“object.getclass().fun()”形式,这样调用更加稳定,避免了return非指定的数据类型的警告。
②输入信息的处理,使用string.contain(),string.split()和string.replace()方法快速处理数据格式,认为比开始上手正则表达式更加适合和便捷,因为输入的数据内容不多,且都是正确信息。
③输入的所有有用信息必须使用.trim()方法去除两边的无用空格。
(2)第二次PTA作业:
①List<class> namelist=new ArrayList<>();语句使用后,该namelist的类型就是List,比如要为一个方法传入给数组时,方法名形参的类型必须是List;同理,当方法返回一个这种数组时,返回的类型也必须时List。
②对于题目要求多个试卷和答卷的形况时,先是一个试卷对应多个答卷还是一个答卷对应多个答卷进行输出呢?经过实践最终证明,一张答卷对应多个答卷。
③在创建对象时就为该对象属性中的数组,即使在类中已经初定义了长度,依然不影响对象的数组属性长度,在使用时可以直接使用“getAttribute.length”表示属性长度,方便对于数组的遍历。
(3)第三次PTA作业:
①对于输入的数据要求增加,不能只用string.contains()来判断输入了,必须先定义每一个标准类型正则表达式,再定义匹配器,不适合的错误信息按要求输出。
②题目要求,对于试卷上的题目,需要判断题目时不存在还是被删除,不仅要对应problemlist进行比对,还要对未进行删除操作的problemlist进行判断。如果未进行删除操作的problemlist找不到就需要立刻输出该题目不存在的信息。
③在删除前保留原始题目列表时,使用“List<Problem> realproblemlist=problemlist”语句,系统不会报错,程序也可以继续运行。但是你会发现那些被删除的题目会显示该题目不存在的提示信息。这里就会产生疑问,我不是新开了一个列表来存储了吗?为什么会找不到呢?实际的原因是,List和ArrayList定义的对象列表,列表名类似与C语言的指针(指向保存数据的地址),所以在语句“List<Problem> realproblemlist=problemlist”中,realproblemlist和problemlist都指向了同一个数据地址。这里正确的方法是“List<Problem> realproblem=new ArrayListProblem<>(problemlist)”,这样就为开辟了一个新的储存空间,并且把未删除的题目信息存入其中。
④对题目的删除功能要区别“list.remove()”中括号内的内容,如果括号内的东西是”n”形式的,那么就会找到n元素,将他从列表中删除;如果没有双引号,那么就会删除第n个元素后面的所有元素。
4. 改进建议
(1)增加类的设计,使得类的职责单一,提高代码的复用性。
(2)类间的关系多元化,关联,依赖,继承等,取消主函数冗长繁杂的问题。
(3)处理输入、数据处理和输出,修改整体设计模式,可以通过MVC设计模式来区块化功能。
(4)正确规范正则表达式,使得错误信息准确输出提示,正确信息准确被存储至固定类。
5.总结
(1)第一次题目设计遵从类的设计建议,完成题目要求实现类的关联,但是信息输入和信息处理以及最终输出都在主函数中;虽然最终得分满分,但设计已经不合理。
(2)第二次题目设计自己学习了List和ArrayList的用法,直接除去了类的关联性,在main函数内设计多种判断、计算和输出的程序结构,自认为结构合理。事实胜于雄辩,最终过不去两个测试点。代码结构不合理,对于第一次代码没有任何改进,只是为了完成题目的垃圾代码!
(3)第三次题目设计再度使用List和Arraylist结构,为方便删除功能在类属性也使用了ArratList,为了满足要求多加了Student和Delect两个基本类设计;为了改变Main类中只有main()方法的单一性,特地多增了方法提供main()方法使用,但是思路依然同前两次的设计没有差异,只是简单的换汤不换药。换句话说就是Main类中的复杂运算与设计,一昧的单一设计思路是无法符合增加难度的题目内容的,最终许许多多的修改才勉强得到及格分数。
(4)第一轮的主要设计思路就是类间的关联性,但是我几乎开始就放弃了类间关联的特性,试图在main方法中设计各种for语句和if语句构成的复杂设计思路实现题目要求。代码复杂,绕来绕去,各种判断限制使得面向对象设计的一篇糊涂。最终也没有办法实现题目要求......

浙公网安备 33010602011771号