总结与思考 : OOP课程 Volumn :1
一.前言
从学习面向过程语言(C为代表)转向学习面向对象语言(Java为代表),疑惑,迷茫,困顿是刚入门OOP的感受。从巨厚无比的计算机黑皮书《Java语言程序设计》,到"方法""函数","类""结构体","实例"等名词术语让我听得雨里雾里,着实令人劝退。特作此Blog记录我才过的坑和OOP学习历程。
二.设计与分析
V1.
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
输入样例1:
单个题目。例如:
1
N:1 #Q:1+1= #A:2
A:2
end
输出样例1:
在这里给出相应的输出。例如:
1+1=~2
true
输入样例2:
单个题目。例如:
1
N:1 #Q:1+1= #A:2
A:4
end
输出样例2:
在这里给出相应的输出。例如:
1+1=~4
false
输入样例3:
多个题目。例如:
2
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
A:2 #A:4
end
输出样例3:
在这里给出相应的输出。例如:
1+1=~2
2+2=~4
true true
输入样例4:
多个题目。例如:
2
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
A:2 #A:2
end
输出样例4:
在这里给出相应的输出。例如:
1+1=~2
2+2=~2
true false
输入样例5:
多个题目,题号顺序与输入顺序不同。例如:
2
N:2 #Q:1+1= #A:2
N:1 #Q:5+5= #A:10
A:10 #A:2
end
输出样例5:
在这里给出相应的输出。例如:
5+5=~10
1+1=~2
true true
输入样例6:
含多余的空格符。例如:
1
N:1 #Q: The starting point of the Long March is #A:ruijin
A:ruijin
end
输出样例6:
在这里给出相应的输出。例如:
The starting point of the Long March is~ruijin
true
输入样例7:
含多余的空格符。例如:
1
N: 1 #Q: 5 +5= #A:10
A:10
end
输出样例7:
在这里给出相应的输出。例如:
5 +5=~10
true
---------------------------------分割线---------------------------------
2.个人设计
点击查看代码
import java.util.Scanner;
//题目类 DONE
class Question{
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Question() {
}
public Question(String content) {
this.content = content;
}
}
//试卷类 问题+标准答案
class Paper {
private Question question;
private String standardAnswer;
public Question getQuestion() {
return question;
}
public Paper() {
}
public String getStandardAnswer() {
return standardAnswer;
}
public void setQuestion(Question question) {
this.question = question;
}
public void setStandardAnswer(String standardAnswer) {
this.standardAnswer = standardAnswer;
}
//答案判定程序
public boolean isRight (Answer answer){
if (standardAnswer.equals(answer.getContent()))
return true;
else
return false;
}
}
//答卷类
class Answer {
private String content;
public Answer() {
}
public Answer(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//储存数据
int size= input.nextInt();
Question [] question=new Question[size];
Paper [] paper=new Paper[size];
Answer [] answer=new Answer[size];
for (int i = 0; i < size; i++) {
question[i] = new Question();
paper[i] = new Paper();
answer[i] = new Answer();
}
input.nextLine();
int actid=0;
for (int i = 0; i < size; i++) {
String line=input.nextLine();
String idText= line.substring(line.indexOf("#N:") + 3, line.indexOf("#Q:")).trim();
String questionText= line.substring(line.indexOf("#Q:") + 3, line.indexOf("#A:")).trim();
String standardAnswerText= line.substring(line.indexOf("#A:") + 3).trim();
//id 号的创建
actid = Integer.parseInt(idText)-1;
//题目
question[actid].setContent(questionText);
paper[actid].setQuestion(question[actid]);
//标准答案
paper[actid].setStandardAnswer(standardAnswerText);
}
for (int i = 0; i < size; i++) {
//用户答案录入 答题纸
String temp=input.next();
String answerText = temp.substring(3);
answer[i].setContent(answerText);
}
for (int i = 0; i < size; i++) {
//输出
System.out.print(paper[i].getQuestion().getContent()+"~"+answer[i].getContent());
System.out.printf("\n");
}
for (int i = 0; i < size; i++) {
//输出
if (i==size-1)
System.out.print(paper[i].isRight(answer[i]));
else
System.out.print(paper[i].isRight(answer[i])+" ");
}
}
}

3.代码分析
本题提前说明了题目数量,可直接使用数组储存数据。由于是第一次接触这种题目,不太会使用正则表达式,尝试了几次未成功,最后使用了String类的方法完成分割数据。这也知致使了1-3次作业的数据处理几乎都使用String方法,而不是正则表达式,在非正常输入时很容易出现意料之外的问题,导致无法全部通过测试点。
由SourceMonitor分析,简单的第一题的的最大复杂度已经接近可接受的上限,信息的处理不合理,大段的代码存在main类里,不合适。
V2
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=5true
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,建议增加答题类,类的内容以及类之间的关联自行设计。
输入样例1:
一张试卷一张答卷。试卷满分不等于100。例如:
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
T:1 1-5 2-8
S:1 #A:5 #A:22
end
输出样例1:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
1+1=5false
2+2=22false
0 0~0
输入样例2:
一张试卷一张答卷。试卷满分不等于100。例如:
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
T:1 1-70 2-30
S:1 #A:5 #A:22
end
输出样例2:
在这里给出相应的输出。例如:
1+1=5false
2+2=22false
0 0~0
输入样例3:
一张试卷、一张答卷。各类信息混合输入。例如:
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
T:1 1-70 2-30
N:3 #Q:3+2= #A:5
S:1 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
1+1=5false
2+2=4true
0 30~30
输入样例4:
试卷题目的顺序与题号不一致。例如:
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
T:1 2-70 1-30
N:3 #Q:3+2= #A:5
S:1 #A:5 #A:22
end
输出样例:
在这里给出相应的输出。例如:
2+2=5false
1+1=22false
0 0~0
输入样例5:
乱序输入。例如:
N:3 #Q:3+2= #A:5
N:2 #Q:2+2= #A:4
T:1 3-70 2-30
S:1 #A:5 #A:22
N:1 #Q:1+1= #A:2
end
输出样例:
在这里给出相应的输出。例如:
3+2=5true
2+2=22false
70 0~70
输入样例6:
乱序输入+两份答卷。例如:
N:3 #Q:3+2= #A:5
N:2 #Q:2+2= #A:4
T:1 3-70 2-30
S:1 #A:5 #A:22
N:1 #Q:1+1= #A:2
S:1 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
3+2=5true
2+2=22false
70 0~70
3+2=5true
2+2=4true
70 30~100
输入样例7:
乱序输入+分值不足100+两份答卷。例如:
N:3 #Q:3+2= #A:5
N:2 #Q:2+2= #A:4
T:1 3-7 2-6
S:1 #A:5 #A:22
N:1 #Q:1+1= #A:2
S:1 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
3+2=5true
2+2=22false
7 0~7
3+2=5true
2+2=4true
7 6~13
输入样例8:
乱序输入+分值不足100+两份答卷+答卷缺失部分答案。例如:
N:3 #Q:3+2= #A:5
N:2 #Q:2+2= #A:4
T:1 3-7 2-6
S:1 #A:5 #A:22
N:1 #Q:1+1= #A:2
T:2 2-5 1-3 3-2
S:2 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
3+2=5true
2+2=22false
7 0~7
2+2=5false
1+1=4false
answer is null
0 0 0~0
输入样例9:
乱序输入+分值不足100+两份答卷+无效的试卷号。例如:
N:3 #Q:3+2= #A:5
N:2 #Q:2+2= #A:4
T:1 3-7 2-6
S:3 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
The test paper number does not exist
---------------------------------分割线---------------------------------
2.个人设计
点击查看代码
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question{
private int id;
private String content;
private String standardAnswer;
private int score;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
this.standardAnswer = standardAnswer;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Question() {
}
public Question(int id, String content, String standardAnswer, int score) {
this.id = id;
this.content = content;
this.standardAnswer = standardAnswer;
this.score = score;
}
}
//判卷程序
class Paper {
private ArrayList<Question> questionList;
private ArrayList<Integer> queueOfPaper;
private int totalScore=0;
public int getTotalScore() {
return totalScore;
}
public void setTotalScore(int totalScore) {
this.totalScore = totalScore;
}
public void judge (Sheet sheet){
int size=sheet.getAnswer().size();
int sizeOfPaper=sheet.getPaper().getQueueOfPaper().size();
for (int i = 0; i < size; i++) {//根据答案的个数 遍历
for (Question each:sheet.getPaper().getQuestionList()){
if (each.getId()==sheet.getPaper().getQueueOfPaper().get(i)){//有问题 输出顺序有问题
int score=each.getScore();
String stdAnswer=each.getStandardAnswer();
String myAnswer=sheet.getAnswer().get(i);
if (stdAnswer.equals(myAnswer)){
sheet.getBool().add(true);
sheet.getActscore().add(score);
}
else {
sheet.getBool().add(false);
sheet.getActscore().add(0);
}
}
}
}
//答案为空
if (size<sizeOfPaper){//临时标记 true 但是0分
sheet.getBool().add(true);
sheet.getActscore().add(0);
}
}
public ArrayList<Integer> getQueueOfPaper() {
return queueOfPaper;
}
public void setQueueOfPaper(ArrayList<Integer> queueOfPaper) {
this.queueOfPaper = queueOfPaper;
}
public Paper(ArrayList<Question> questionList, ArrayList<Integer> queueOfPaper) {
this.questionList = questionList;
this.queueOfPaper = queueOfPaper;
}
public ArrayList<Question> getQuestionList() {
return questionList;
}
public void setQuestionList(ArrayList<Question> questionList) {
this.questionList = questionList;
}
public Paper(ArrayList<Question> questionList) {
this.questionList = questionList;
}
public Paper() {
this.queueOfPaper=new ArrayList<>(5);
this.questionList=new ArrayList<>(5);
}
}
class Sheet{
private Paper paper;
private ArrayList<String> answer;
private ArrayList<Boolean> bool;
private ArrayList<Integer> actscore;
private int belongToWhichPaper=0;
private int totalScore;
public int getTotalScore() {
return totalScore;
}
public void setTotalScore(int totalScore) {
this.totalScore = totalScore;
}
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public ArrayList<String> getAnswer() {
return answer;
}
public void setAnswer(ArrayList<String> answer) {
this.answer = answer;
}
public ArrayList<Boolean> getBool() {
return bool;
}
public void setBool(ArrayList<Boolean> bool) {
this.bool = bool;
}
public ArrayList<Integer> getActscore() {
return actscore;
}
public void setActscore(ArrayList<Integer> actscore) {
this.actscore = actscore;
}
public int getBelongToWhichPaper() {
return belongToWhichPaper;
}
public void setBelongToWhichPaper(int belongToWhichPaper) {
this.belongToWhichPaper = belongToWhichPaper;
}
public Sheet(Paper paper, ArrayList<String> answer, ArrayList<Boolean> bool, ArrayList<Integer> actscore, int belongToWhichPaper, ArrayList<Integer> queueID) {
this.paper = paper;
this.answer = answer;
this.bool = bool;
this.actscore = actscore;
this.belongToWhichPaper = belongToWhichPaper;
}
public Sheet() {
this.answer=new ArrayList<>(5);
this.bool=new ArrayList<>(5);
this.actscore=new ArrayList<>(5);
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Paper[] paper = new Paper[2];
Sheet[] sheet = new Sheet[2];
paper[0]=new Paper();paper[1]=new Paper();
sheet[0]=new Sheet();sheet[1]=new Sheet();
sheet[0].setPaper(paper[0]);
sheet[1].setPaper(paper[1]);
int timeOfSheet=0;
int timeOfT=0;
while (true) {
String line = input.nextLine();
//题目
if (line.contains("#N:")) {//问题
String idText = line.substring(line.indexOf("#N:") + 3, line.indexOf("#Q:")).trim();
int id = Integer.parseInt(idText);
String questionText = line.substring(line.indexOf("#Q:") + 3, line.indexOf("#A:")).trim();
String standardAnswerText = line.substring(line.indexOf("#A:") + 3).trim();
Question questionTemp = new Question();
questionTemp.setId(id);
questionTemp.setContent(questionText);
questionTemp.setStandardAnswer(standardAnswerText);
paper[0].getQuestionList().add(questionTemp);
//克隆给1
Question questionTemp1 = new Question();
questionTemp1.setId(id);
questionTemp1.setContent(questionText);
questionTemp1.setStandardAnswer(standardAnswerText);
paper[1].getQuestionList().add(questionTemp1);
}
//试卷 输出的题号和分数 对应着输出顺序
else if (line.contains("#T:")) {
String paperIDTEXT = line.substring(line.indexOf("#N:") + 4, line.indexOf("#N:") + 5);
int paperId = Integer.parseInt(paperIDTEXT);// 试卷号
Pattern pattern = Pattern.compile("(\\d+)-(\\d+)");
Matcher matcher = pattern.matcher(line);
if (paperId == 1) {//属于第一套试卷
timeOfT++;
while (matcher.find()) {
sheet[0].setBelongToWhichPaper(1);
String idtext = matcher.group(1);
int id = Integer.parseInt(idtext);//题号
String scoretext = matcher.group(2);
int score = Integer.parseInt(scoretext);//分数
int i=0;
for (Question questiontemp : paper[0].getQuestionList()) {
if (questiontemp.getId() == id) {
questiontemp.setScore(score);
paper[0].getQueueOfPaper().add(id);
i++;
break;
}
}
}
}
else if (paperId == 2) {
timeOfT++;
while (matcher.find()) {
sheet[1].setBelongToWhichPaper(2);
String idtext = matcher.group(1);
int id = Integer.parseInt(idtext);//题号
String scoretext = matcher.group(2);
int score = Integer.parseInt(scoretext);//分数
int i=0;
for (Question questiontemp : paper[1].getQuestionList()) {
if (questiontemp.getId() == id) {
questiontemp.setScore(score);
paper[1].getQueueOfPaper().add(id);//改
i++;
break;
}
}
}
}
}
//答卷 答案
else if (line.contains("#S:")) {//#s 属于哪一个试卷
String idSheet = line.substring(line.indexOf("#S:") + 3, line.indexOf("#S:") + 4);
int id = Integer.parseInt(idSheet);//试卷id 属于哪一个试卷
String[] words = line.split(" ");
if (timeOfSheet == 0) {
timeOfSheet++;
sheet[0].setBelongToWhichPaper(id);
for (int i = 1; i < words.length; i++) {
words[i] = words[i].substring(words[i].indexOf("#A:") + 3);
sheet[0].getAnswer().add(words[i]);
}
if (id==2)
sheet[0].setPaper(sheet[1].getPaper());
}
else {
timeOfSheet++;
sheet[1].setBelongToWhichPaper(id);
for (int i = 1; i < words.length; i++) {
words[i] = words[i].substring(words[i].indexOf("#A:") + 3);
sheet[1].getAnswer().add(words[i]);
}
if (id==1)
sheet[1].setPaper(sheet[0].getPaper());
}
}
else if (line.contains("end"))
break;//结束条件判断
}
//统计总分
for (int i = 0; i < 2; i++) {
int totoalScore=0;
for (Question each:sheet[i].getPaper().getQuestionList()){
totoalScore+=each.getScore();
}
sheet[i].getPaper().setTotalScore(totoalScore);
}
for (int i = 0; i < 2; i++) {
if (paper[i].getTotalScore()!=100)
System.out.println("alert: full score of test paper"+(i+1)+" is not 100 points");
if (timeOfT==1)break;
}
//判卷
boolean exit=false;
for (int i = 0; i < 2; i++) {
if(sheet[i].getBelongToWhichPaper()==1)
paper[0].judge(sheet[i]);
else if (sheet[i].getBelongToWhichPaper()==2) {
paper[1].judge(sheet[i]);
}
else {
System.out.print("The test paper number does not exist");
return;
}
if (timeOfSheet==1)break;
}
//求实际总分
for (int i = 0; i < 2; i++) {
int totalScore=0;
for (int j = 0; j < sheet[i].getActscore().size(); j++) {
totalScore+=sheet[i].getActscore().get(j);
}
sheet[i].setTotalScore(totalScore);
}
//卷子 详情输出
int []outputTimes=new int[2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < sheet[i].getBool().size(); j++) {
outputTimes[i]++;
if (sheet[i].getBool().get(j)==true&&sheet[i].getActscore().get(j)==0)
outputTimes[i]--;
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < sheet[i].getBool().size(); j++) {
if (sheet[i].getBool().get(j)==true&&sheet[i].getActscore().get(j)==0) {
System.out.println("answer is null");
}
else {
String q = null;
for (Question each : sheet[i].getPaper().getQuestionList()) {
int id = each.getId();
if (id == sheet[i].getPaper().getQueueOfPaper().get(j)) {
q = each.getContent();
break;
}
}
System.out.println(q + "~" + sheet[i].getAnswer().get(j) + "~" + sheet[i].getBool().get(j));
}
}
//小题分数输出
for (int j = 0;j<sheet[i].getBool().size(); j++) {
if (j==0)
System.out.print(sheet[i].getActscore().get(j));
else
System.out.print(" "+sheet[i].getActscore().get(j));
}
System.out.print("~"+sheet[i].getTotalScore());
if (timeOfSheet==1)break;
if(i!=1) System.out.print("\n");
}
}
}//样例8


3.代码分析
没有意识到Java的核心在于类的设计,此题增加了试卷信息,重复输出,answer is null的判断等操作。在第一次编写代码时,已经存在大量问题,此次作业仍然没想到增加类,只想着在原有的类设计上增加类的属性,以完成PTA的任务,结局是:即便有大量注释,代码可读性仍然很差,维护性差,前一天晚上编写的代码,第二天就忘掉了思路,看不懂了自己写的代码了。
我的代码虽然得了60/73分,但未通过的测试点都是样例中不存在的情况。我觉得是功能模块设计出了问题,每个模块分的太大了,一个模块会执行很多个小模块的操作,调试,阅读时都不太方便。但是如果将功能分成小块,我又会花很对时间来考虑方法的传入参数问题。归根到底,是结构化设计出了问题。
根据SourceMonitor分析,代码的平均深度,最大深度,最大复杂度都爆表了,佐证了我的判断。因此,在以后的设计中,不要怕类的属性多,方法多。实际上,Java编码就在于类的编写,而不是很多操作在main函数里执行。
1.属性编写问题
当我们new 一个Sheet实例时,先会执行属性的初始化,再是构造方法,由于我编写的代码只是初始化,没有给其中的类和链表赋值,会出现“xx=null”的情况,我当时的解决办法是在构造方法new实例,现查看其他同学的代码学习到在属性的编写时new实例更加方便,高效。
2.对answer is null处理问题
取巧,发现样例答案不存在都在最后一个答案中,设计的处理方法也只对最后一个答案有效。我的处理时Boolean设为true,分数设置为0,与其他正常条件区分开,实际上,boolean设置为分数设置为0,判断结果可以不用设置,在以后处理中只需要判断是否“answer is null”即可。
V3
由于我继续沿用之前题目的类设计,再加之周末时间紧张,导致遇到新需求时,程序彻底崩盘,只得了基础6/84分,不多做赘述。
点击查看代码
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question{
private int id;
private String content;
private String standardAnswer;
private int score;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
this.standardAnswer = standardAnswer;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Question() {
}
public Question(int id, String content, String standardAnswer, int score) {
this.id = id;
this.content = content;
this.standardAnswer = standardAnswer;
this.score = score;
}
}
//判卷程序
class Paper {
private ArrayList<Question> questionList;
private ArrayList<Integer> queueOfPaper;
private int totalScore=0;
public int getTotalScore() {
return totalScore;
}
public void setTotalScore(int totalScore) {
this.totalScore = totalScore;
}
public void judge (Sheet sheet){
int size=sheet.getAnswer().size();
int sizeOfPaper=sheet.getPaper().getQueueOfPaper().size();
for (int i = 0; i < size&&i<sizeOfPaper; i++) {//根据答案的个数 遍历
for (Question each:sheet.getPaper().getQuestionList()){
if (each.getId()==sheet.getPaper().getQueueOfPaper().get(i)){//有问题 输出顺序有问题
int score=each.getScore();
String stdAnswer=each.getStandardAnswer();
String myAnswer=sheet.getAnswer().get(i);
if (stdAnswer.equals(myAnswer)){
sheet.getBool().add(true);
sheet.getActscore().add(score);
}
else {
sheet.getBool().add(false);
sheet.getActscore().add(0);
}
}
}
}
//答案为空
if (size<sizeOfPaper){//临时标记 true 但是0分
sheet.getBool().add(true);
sheet.getActscore().add(0);
}
}
public ArrayList<Integer> getQueueOfPaper() {
return queueOfPaper;
}
public void setQueueOfPaper(ArrayList<Integer> queueOfPaper) {
this.queueOfPaper = queueOfPaper;
}
public Paper(ArrayList<Question> questionList, ArrayList<Integer> queueOfPaper) {
this.questionList = questionList;
this.queueOfPaper = queueOfPaper;
}
public ArrayList<Question> getQuestionList() {
return questionList;
}
public void setQuestionList(ArrayList<Question> questionList) {
this.questionList = questionList;
}
public Paper(ArrayList<Question> questionList) {
this.questionList = questionList;
}
public Paper() {
this.queueOfPaper=new ArrayList<>(5);
this.questionList=new ArrayList<>(5);
}
}
class Sheet{
private Paper paper;
private ArrayList<String> answer;
private ArrayList<Boolean> bool;
private ArrayList<Integer> actscore;
private int belongToWhichPaper=0;
private int totalScore;
public int getTotalScore() {
return totalScore;
}
public void setTotalScore(int totalScore) {
this.totalScore = totalScore;
}
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public ArrayList<String> getAnswer() {
return answer;
}
public void setAnswer(ArrayList<String> answer) {
this.answer = answer;
}
public ArrayList<Boolean> getBool() {
return bool;
}
public void setBool(ArrayList<Boolean> bool) {
this.bool = bool;
}
public ArrayList<Integer> getActscore() {
return actscore;
}
public void setActscore(ArrayList<Integer> actscore) {
this.actscore = actscore;
}
public int getBelongToWhichPaper() {
return belongToWhichPaper;
}
public void setBelongToWhichPaper(int belongToWhichPaper) {
this.belongToWhichPaper = belongToWhichPaper;
}
public Sheet(Paper paper, ArrayList<String> answer, ArrayList<Boolean> bool, ArrayList<Integer> actscore, int belongToWhichPaper, ArrayList<Integer> queueID) {
this.paper = paper;
this.answer = answer;
this.bool = bool;
this.actscore = actscore;
this.belongToWhichPaper = belongToWhichPaper;
}
public Sheet() {
this.answer=new ArrayList<>(5);
this.bool=new ArrayList<>(5);
this.actscore=new ArrayList<>(5);
}
}
class Student{
private String id;
private String name;
Sheet mysheet;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Sheet getMysheet() {
return mysheet;
}
public void setMysheet(Sheet mysheet) {
this.mysheet = mysheet;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Paper[] paper = new Paper[2];
Sheet[] sheet = new Sheet[2];
Student[] student=new Student[2];
paper[0]=new Paper();paper[1]=new Paper();
sheet[0]=new Sheet();sheet[1]=new Sheet();
student[0]=new Student();student[1]=new Student();
sheet[0].setPaper(paper[0]);
sheet[1].setPaper(paper[1]);
int timeOfSheet=0;
int timeOfT=0;
while (true) {
String line = input.nextLine();
//题目
if (line.contains("#N:")) {//问题
String idText = line.substring(line.indexOf("#N:") + 3, line.indexOf("#Q:")).trim();
int id = Integer.parseInt(idText);
String questionText = line.substring(line.indexOf("#Q:") + 3, line.indexOf("#A:")).trim();
String standardAnswerText = line.substring(line.indexOf("#A:") + 3).trim();
Question questionTemp = new Question();
questionTemp.setId(id);
questionTemp.setContent(questionText);
questionTemp.setStandardAnswer(standardAnswerText);
paper[0].getQuestionList().add(questionTemp);
//克隆给1
Question questionTemp1 = new Question();
questionTemp1.setId(id);
questionTemp1.setContent(questionText);
questionTemp1.setStandardAnswer(standardAnswerText);
paper[1].getQuestionList().add(questionTemp1);
}
//试卷 输出的题号和分数 对应着输出顺序
else if (line.contains("#T:")) {
String paperIDTEXT = line.substring(line.indexOf("#N:") + 4, line.indexOf("#N:") + 5);
int paperId = Integer.parseInt(paperIDTEXT);// 试卷号
Pattern pattern = Pattern.compile("(\\d+)-(\\d+)");
Matcher matcher = pattern.matcher(line);
if (paperId == 1) {//属于第一套试卷
timeOfT++;
while (matcher.find()) {
sheet[0].setBelongToWhichPaper(1);
String idtext = matcher.group(1);
int id = Integer.parseInt(idtext);//题号
String scoretext = matcher.group(2);
int score = Integer.parseInt(scoretext);//分数
int i=0;
for (Question questiontemp : paper[0].getQuestionList()) {
if (questiontemp.getId() == id) {
questiontemp.setScore(score);
paper[0].getQueueOfPaper().add(id);
i++;
break;
}
}
}
}
else if (paperId == 2) {
timeOfT++;
while (matcher.find()) {
sheet[1].setBelongToWhichPaper(2);
String idtext = matcher.group(1);
int id = Integer.parseInt(idtext);//题号
String scoretext = matcher.group(2);
int score = Integer.parseInt(scoretext);//分数
int i=0;
for (Question questiontemp : paper[1].getQuestionList()) {
if (questiontemp.getId() == id) {
questiontemp.setScore(score);
paper[1].getQueueOfPaper().add(id);//改
i++;
break;
}
}
}
}
}
//答卷 答案
else if (line.contains("#S:")) {//#s 属于哪一个试卷
//#S:1 20201103 #A:1-5
String idSheet = line.substring(line.indexOf("#S:") + 3, line.indexOf("#S:") + 4);
int id = Integer.parseInt(idSheet);//试卷id 属于哪一个试卷
line=line.substring(line.indexOf("#A:"));
line=line.substring(3);
String[] words = line.split(" ");
if (timeOfSheet == 0) {
timeOfSheet++;
sheet[0].setBelongToWhichPaper(id);
for (int i = 0; i < words.length; i++) {
Pattern pattern = Pattern.compile("(\\d+)-(\\d+)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
sheet[0].getAnswer().add(matcher.group(2));
}
}
if (id==2)
sheet[0].setPaper(sheet[1].getPaper());
}
else {
timeOfSheet++;
sheet[1].setBelongToWhichPaper(id);
for (int i = 0; i < words.length; i++) {
words[i] = words[i].substring(words[i].indexOf("#A:") + 3);
sheet[1].getAnswer().add(words[i]);
Pattern pattern = Pattern.compile("(\\d+)-(\\d+)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
sheet[1].getAnswer().add(matcher.group(2));
}
}
if (id==1)
sheet[1].setPaper(sheet[0].getPaper());
}
}
else if (line.contains("#X:")){
line=line.substring(3);
String []words=line.split(" ");
student[0].setId(words[0]);
student[0].setName(words[1]);
}
else if (line.contains("end"))
break;//结束条件判断
}
//统计总分
for (int i = 0; i < 2; i++) {
int totoalScore=0;
for (Question each:sheet[i].getPaper().getQuestionList()){
totoalScore+=each.getScore();
}
sheet[i].getPaper().setTotalScore(totoalScore);
}
for (int i = 0; i < 2; i++) {
if (paper[i].getTotalScore()!=100)
System.out.println("alert: full score of test paper"+(i+1)+" is not 100 points");
if (timeOfT==1)break;
}
//判卷
boolean exit=false;
for (int i = 0; i < 2; i++) {
if(sheet[i].getBelongToWhichPaper()==1)
paper[0].judge(sheet[i]);
else if (sheet[i].getBelongToWhichPaper()==2) {
paper[1].judge(sheet[i]);
}
else {
System.out.print("The test paper number does not exist");
return;
}
if (timeOfSheet==1)break;
}
//求实际总分
for (int i = 0; i < 2; i++) {
int totalScore=0;
for (int j = 0; j < sheet[i].getActscore().size(); j++) {
totalScore+=sheet[i].getActscore().get(j);
}
sheet[i].setTotalScore(totalScore);
}
//卷子 详情输出
int []outputTimes=new int[2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < sheet[i].getBool().size(); j++) {
outputTimes[i]++;
if (sheet[i].getBool().get(j)==true&&sheet[i].getActscore().get(j)==0)
outputTimes[i]--;
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < sheet[i].getBool().size(); j++) {
if (sheet[i].getBool().get(j)==true&&sheet[i].getActscore().get(j)==0) {
System.out.println("answer is null");
}
else {
String q = null;
for (Question each : sheet[i].getPaper().getQuestionList()) {
int id = each.getId();
if (id == sheet[i].getPaper().getQueueOfPaper().get(j)) {
q = each.getContent();
break;
}
}
System.out.println(q + "~" + sheet[i].getAnswer().get(j) + "~" + sheet[i].getBool().get(j));
}
}
//小题分数输出
System.out.print(student[0].getId()+" "+student[0].getName()+": ");
for (int j = 0;j<sheet[i].getBool().size(); j++) {
if (j==0)
System.out.print(sheet[i].getActscore().get(j));
else
System.out.print(" "+sheet[i].getActscore().get(j));
}
System.out.print("~"+sheet[i].getTotalScore());
if (timeOfSheet==1)break;
if(i!=1) System.out.print("\n");
}
}
}
三.心得
1.程序的需求是一定会变化的,不能存有侥幸心理,觉得等到需求改变时再重构代码,这是巨大的工作量。在一开始设计师,无论项目大小,都应该适应变化,用抽象类,,继承,多态,接口等应对这些变化。
2.此门课程的核心实际不是Java的算法,而是OOP的设计。不同于C,学习ArrayList这些新的数据结构只是这门课的基础,这门课的核心实际上是掌握并运用OOP的设计模式。“工欲善其事必先利其器”,拥有好的类设计,必定会是问题解决事半功倍。
3.每一个输出,都对应着某个类的方法,只是根据条件是否触发。
4.在Java学习和PTA实践中,缺少与同学的合作与交流。不清楚其他人的学习进度,颇有井底之蛙之感。
四.课程建议
1.建议在PTA作业上给出提示,需要利用哪些知识点,哪些新内容,以方便我们自学。
2.可以推荐一些“入门级”OOP的设计模式的资料。
23201837 李茂田
2024-4-21 16:52

浙公网安备 33010602011771号