总结与思考 : 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

posted @ 2024-04-21 16:34  FreeMorty  阅读(20)  评论(0)    收藏  举报