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。其中类与类的关系用到了关联,其属性和方法以及类间关系如下图。

屏幕截图 2024-04-20 192616

①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方法发中代码繁冗,并且并不是所有测试点都可以通过。类图如下:

屏幕截图 2024-04-20 222324

①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形式的数组,方便删除、添加和遍历。但仅仅这些设计是完全不够题目要求的,也不符合面向对象设计的整体需求,最后经过不断的修改任然无法满足所有测试点,只能通过部分测试点。

类图如下:

屏幕截图 2024-04-21 003759

①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语句构成的复杂设计思路实现题目要求。代码复杂,绕来绕去,各种判断限制使得面向对象设计的一篇糊涂。最终也没有办法实现题目要求......

posted @ 2024-04-21 20:03  Stone_nix  阅读(33)  评论(2)    收藏  举报