PTA第一階段三次作業總結

来源:https://www.cnblogs.com/Chew-Cherry/p/18148769/homo-1145141919810
-Advertisement-
Play Games

前言 這學期剛剛接觸面向對象程式設計,使用的是java語言。在此之前只接觸過c語言。以我目前的學習進程來看二者的差別更多體現在面向對象的其中一個基本特性上,即封裝性。在c語言中幾乎所有內容都是公開的,java可以有效得規避這點。 學習的知識點 1.知道了類間關係。面向對象程式設計中要根據實際情況合理 ...


前言

前三次PTA的題目集合,主要考察的知識點有:面向對象程式設計的封裝性,正則表達式的運用,數組和ArrayList的運用,日期類的運用, 類間關係(關聯,依賴,組合,聚合)幾個主要的知識點。三次作業共計12題,其中大部分題目都與面向對象程式設計的封裝性和正則表達式的運用有關。每次作業的最後一題難度較大,其他題目比較簡單,通常是半天寫完前面所有題目,剩下的5天用來攻剋最後一題。在做題的過程中,我初步瞭解了面向對象程式設計的基本要領,比如,類要保持單一職責原則,類內部的方法一般不超過60行等。以下是對三次PTA作業最後一題的分析:

7-5 答題判題程式-1

分數 74
困難
作者 蔡軻
單位 南昌航空大學
設計實現答題程式,模擬一個小型的測試,要求輸入題目信息和答題信息,根據輸入題目信息中的標準答案判斷答題的結果。

輸入格式:
程式輸入信息分三部分:

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

設計建議:
以下是針對以上題目要求的設計建議,其中的屬性、方法為最小集,實現代碼中可根據情況添加所需的內容:

題目類(用於封裝單個題目的信息):

屬性:題目編號、題目內容、標準答案-standardAnswer
方法:數據讀寫set\get方法、
判題方法(答案-answer):判斷答案-answer是否符合標準答案-standardAnswer
試卷類(用於封裝整套題目的信息)

屬性:題目列表(題目類的對象集合)、題目數量
方法:判題方法(題號-num、答案-answer):判斷答案-answer是否符合對應題號的題目標準答案-standardAnswer
保存題目(題號-num、題目-question):將題目保存到題目列表中,保存位置與num要能對應
答卷類(用於封裝答題信息)

屬性:試卷(試卷類的對象)、答案列表(保存每一題的答案)、判題列表(保存每一題的判題結果true/false)
方法:判題方法(題號-num):判斷答案列表中第num題的結果是否符合試卷中對應題號的題目標準答案
輸出方法(題號-num):按照題目的格式要求,輸出題號為num的題目的內容和答題結果。
保存一個答案(題號-num,答案-answer):保存題號為num的題目的答題結果answer。

題目分析
這道題目的要求是輸入一定量的題目,再輸入這些題目的信息和答題信息,輸出答題的正誤。
通過這些信息,我們初步進行設計,分為三個實體類:Question(題目類),Textpaper(試卷類),AnswerSheet(答卷類),類間關係為下圖:

代碼分析
代碼如下:


class Subject{
    private int num = 0;
    private String content;
    private String standardAnswer;

    public Subject(){
        
    }

    public Subject(int num, String content, String standardAnswer){
        this.num = num;
        this.content = content;
        this.standardAnswer = standardAnswer;
    }

    public int getnum(){
        return this.num;
    }

    public void setnum(int num){
        this.num = num;
    }

    public String getcontent(){
        return this.content;
    }

    public void setcontent(String content){
        this.content = content;
    }

    public String getstandardAnswer(){
        return this.standardAnswer;
    }

    public void setstandardAnswer(String standardAnswer){
        this.standardAnswer = standardAnswer;
    }
}

class textPaper{
    private int sum = 0;
    private Subject[] sub = new Subject[1];

    public textPaper(){
        
    }
    
    public void setpaper(int sum, int num, String content, String standardAnswer){
        this.sum = sum;
        this.sub[num] = new Subject();
        sub[num].setnum(num);
        sub[num].setcontent(content);
        sub[num].setstandardAnswer(standardAnswer);
    }

    public void initsub(int sum){
        this.sub = new Subject[sum];
    }
    
    public int getsum(){
        return this.sum;
    }

    public void setsum(int sum){
        this.sum = sum;
    }
    
    public Subject[] getsubject(){
        return this.sub;
    }

    public void setsubject(Subject[] sub){
        this.sub = sub;
    }
    
    public boolean judge(int num, String answer){
        if(this.sub[num].getstandardAnswer().equals(answer))
            return true;
        else
            return false;
    }

    public void saveSubject(int num, String question){
        this.sub[num].setnum(num + 1);
        this.sub[num].setcontent(question);
    }
}

class answerSheet{
    private textPaper paper = new textPaper();
    private String[] answerList;
    private boolean[] judgeList;

    public answerSheet(){
        
    }

    public textPaper gettextPaper() {
        return this.paper;
    }
    
    public void settextPaper(int sum, int num, String content, String standardAnswer) {
    	this.paper.setpaper(sum, num, content, standardAnswer);

    } 
    
    public String[] getanswerList() {
    	return answerList;
    }

    public void initsub(int sum){
        this.paper.initsub(sum);
    }
    
    public void initList(int sum){
        answerList = new String[sum];
        judgeList = new boolean[sum];
    }
    
    public void setanswerList(int num, String answer) {
    	answerList[num] = new String();
    	answerList[num] = answer;
    }
    
    public boolean[] getjudgeList() {
    	return judgeList;
    }
    
    public void setjudgeList(int num, boolean value) {
    	judgeList[num] = value;
    }
    
    public void judgement(int num){
        if (paper.judge(num, answerList[num]))
            setjudgeList(num, true);
        else
            setjudgeList(num, false);
    }

    public void printof(int num){
        System.out.printf("%s~%s\n", this.paper.getsubject()[num].getcontent(), answerList[num]);
    }

    public void printof2(int num){
        System.out.printf("%b", this.judgeList[num]);
    }
}

public class Main{

	public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        answerSheet answersheet = new answerSheet();
        int sum = scan.nextInt();
        answersheet.initsub(sum);
        answersheet.initList(sum);
        String a = scan.nextLine();
        for (int i = 0; i < sum; i++){
            String str = scan.nextLine();
            String[] strs = str.split("\\s*#N:\\s*|\\s*#Q:\\s*|\\s*#A:\\s*");
            //System.out.printf("%d %d %s %s\n", sum, i, strs[2], strs[3]);
            answersheet.settextPaper(sum, Integer.parseInt(strs[1]) - 1, strs[2], strs[3]);
        }
        String str2 = scan.nextLine();    
    	String[] strs2 = str2.split("\\s*#A:\\s*");
        for (int i = 0; i < sum; i++) {
        	//System.out.printf("%d\n", strs2.length);
        	answersheet.setanswerList(i, strs2[i + 1]);
            answersheet.printof(i);
        }
        for (int i = 0; i < sum; i++){
            answersheet.judgement(i);
        	answersheet.printof2(i);
            if (i != sum - 1)
                System.out.printf(" ");
        }
	}
}

測試點結果如圖:

該代碼存在以下幾個問題:
1.對輸入數據的處理沒有單獨設置一個類,沒有保證主函數內只有輸入輸出功能,屬於結構設計的錯誤;
2.在answerSheet類內部有很多不應該在其內部的方法,沒有保證類單一職責原則,類間耦合性高,屬於結構設計的錯誤;
3.命名不規範,如題目類應該為Question類,而非Subject類,變數命名也不規範,如sum指代的變數功能不明確等,屬於格式書寫的錯誤;

從這段代碼中學到的:
1.設計類的時候要主要單一職責原則,如果不能符合單一職責原則,後面的擴展會非常麻煩,而且要不斷的重構;
2.主函數內部不應該出現對數據進行處理的部分,這些部分應該在一個類中實現;
3.即使題目簡單,也要為後面題目複雜化而考慮,每次設計都不能只針對當前的情況進行設計,要時刻記住代碼的可擴展性;

踩坑心得
1.開始在處理輸入的時候,忽略了輸入的第一個數字後面的空格,導致下麵的字元串全部沒辦法被讀取,在加上了一個scan.nextLine();後成功解決了這個問題;
2.題目的輸入順序是亂序的,不一定按照題號順序輸出的,開始的時候沒有考慮到,導致創建的數組總是莫名其妙地越界,後面及時發現了這個問題,就以題號的順序進行保存,解決了這個問題;
3.答案的輸出的先後順序是按照題號的順序輸出的,開始的時候輸出錯了,導致全部是答案錯誤,最後認真讀題發現了輸出的邏輯錯了,及時改正解決了這個問題,所以一定要認真讀題,先讀10遍題目再開始設計;

改進建議
1.增加一個Control類,把輸入處理的部分放在這個類裡面,這樣既降低了類間耦合性,又保證了單一職責原則;
2.更改命名方式,以實際作用編寫類名,方法名,變數名,提高代碼可讀性。

7-4 答題判題程式-2

分數 73
困難
作者 蔡軻
單位 南昌航空大學
設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-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=~5~false
2+2=~22~false
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=~5~false
2+2=~22~false
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=~5~false
2+2=~4~true
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=~5~false
1+1=~22~false
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=~5~true
2+2=~22~false
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=~5~true
2+2=~22~false
70 0~70
3+2=~5~true
2+2=~4~true
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=~5~true
2+2=~22~false
7 0~7
3+2=~5~true
2+2=~4~true
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=~5~true
2+2=~22~false
7 0~7
2+2=~5~false
1+1=~4~false
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

題目分析
這道題目相比於前一題,在輸入上增加了兩種情況,要求對特殊情況的判斷也增多了,如答題為空,試卷為空等情況。這種情況下應該增加類,如保存輸入信息的類,保存一張試卷中題目分數的類。這兩個類與answerSheet類的類間關係應該為依賴。實際代碼類圖如圖:

代碼分析
代碼如下:

import java.util.*;

class Subject{
    private int num = 0;
    private String content;
    private String standardAnswer;

    public Subject(){
        
    }

    public Subject(int num, String content, String standardAnswer){
        this.num = num;
        this.content = content;
        this.standardAnswer = standardAnswer;
    }

    public int getnum(){
        return this.num;
    }

    public void setnum(int num){
        this.num = num;
    }

    public String getcontent(){
        return this.content;
    }

    public void setcontent(String content){
        this.content = content;
    }

    public String getstandardAnswer(){
        return this.standardAnswer;
    }

    public void setstandardAnswer(String standardAnswer){
        this.standardAnswer = standardAnswer;
    }
}

class textPaper{
    private int sum = 0;
    private Subject[] sub = new Subject[1];

    public textPaper(){
        
    }
    
    public void setpaper(int num, int nums, String content, String standardAnswer){
        this.sub[num] = new Subject();
        sub[num].setnum(nums);
        sub[num].setcontent(content);
        sub[num].setstandardAnswer(standardAnswer);
    }

    public void initsub(int sum){
        this.sub = new Subject[sum];
    }
    
    public int getsum(){
        return this.sum;
    }

    public void setsum(int sum){
        this.sum = sum;
    }
    
    public Subject[] getsubject(){
        return this.sub;
    }

    public void setsubject(Subject[] sub){
        this.sub = sub;
    }
    
    public boolean judge(int num, String answer){
        if(this.sub[num].getstandardAnswer().equals(answer))
            return true;
        else
            return false;
    }

    public void saveSubject(int num, String question){
        this.sub[num].setnum(num + 1);
        this.sub[num].setcontent(question);
    }
}

class testPaper{
	private int[] score;
	private int[] realscore;
	private int[] sitearr;
	
	public testPaper() {
		
	}
	
	public testPaper(int[] score) {
		this.score = score;
	}
	
	public int[] getScore() {
		return this.score;
	}
	
	public void setScore(int num, int scores) {
		this.score[num] = scores;
	}
	
	public int[] getrealScore() {
		return this.realscore;
	}
	
	public void setrealScore(int num, int scores) {
		this.realscore[num] = scores;
	}
	
	public int[] getsitearr() {
		return this.sitearr;
	}
	
	public void setsitearr(int num, int site) {
		this.sitearr[num] = site;
	}
	
	public void initarr(int max) {
		this.score = new int[max];
		this.realscore = new int[max];
		this.sitearr = new int[max];
		for (int i = 0; i < sitearr.length; i++) {
			sitearr[i] = -1;
		}
	}
	
	public int getreallength() {
		int sum = 0;
		for (int i = 0; i < score.length; i++) {
			if (score[i] != 0)
				sum++;
		}
		
		return sum;
	}
	
	public int Nonzero(int value) {
		return score[value];
	}
	
	public int allScore() {
		int allscore = 0;
		for (int i = 0; i < score.length; i++) {
			allscore += score[i];
		}
		
		return allscore;
	}
	
	public int allrealScore() {
		int allscore = 0;
		for (int i = 0; i < realscore.length; i++) {
			allscore += realscore[i];
		}
		
		return allscore;
	}
}

class answerSheet{
    private textPaper paper = new textPaper();
    private String[] answerList;
    private boolean[] judgeList;
    private testPaper[] Testpaper;

    public answerSheet(){
        
    }

    public textPaper gettextPaper() {
        return this.paper;
    }
    
    public void settextPaper(int num, int nums, String content, String standardAnswer) {
    	this.paper.setpaper(num, nums, content, standardAnswer);

    } 
    
    public String[] getanswerList() {
    	return answerList;
    }

    public void initsub(int sum){
        this.paper.initsub(sum);
    }
    
    public void initList(int sum){
        this.answerList = new String[sum];
        this.judgeList = new boolean[sum];
    }
    
    public void initpaper(int sum) {
    	this.Testpaper = new testPaper[sum];
    }
    
    public void setanswerList(int num, String answer) {
    	answerList[num] = new String();
    	answerList[num] = answer;
    }
    
    public boolean[] getjudgeList() {
    	return judgeList;
    }
    
    public void setjudgeList(int num, boolean value) {
    	judgeList[num] = value;
    }
    
    public void judgement(int num){
        if (paper.judge(num, answerList[num])) {
            setjudgeList(num, true);
            
        }else {
            setjudgeList(num, false);
        }
    }

    public void scored(int num, int nums) {
    	if (judgeList[nums]) {
    		Testpaper[num].setrealScore(nums, Testpaper[num].getScore()[nums]);
    	}else {
    		Testpaper[num].setrealScore(nums, 0);
    	}
    }
    
    public testPaper[] gettestpaper() {
    	return this.Testpaper;
    }
    
    public void settestpaper(int num, int nums, int scores) {
    	Testpaper[num].setScore(nums, scores);
    }
    
    public void setsite(int num, int nums, int site) {
    	//System.out.printf("%d %d %d\n", num, nums, site);
    	Testpaper[num].setsitearr(nums, site);
    }
    
    public void initpapers(int num) {
    	Testpaper[num] = new testPaper();
    }
    
    public void initarr(int num, int max) {
    	Testpaper[num].initarr(max);
    }
    
    public boolean Nonzero(int num, int value) {
    	if (Testpaper[num].Nonzero(value) != 0)
    		return true;
    	else
    		return false;
    	
    }
    
    public void judgescore(int num) {
    	if (Testpaper[num].allScore() != 100) {
    		System.out.printf("alert: full score of test paper%d is not 100 points\n", num + 1);
    	}
    }
    
    public void printof(int num){
        if (answerList[num] == null){
            System.out.printf("answer is null\n");
        } else {
            System.out.printf("%s~%s~%b\n", this.paper.getsubject()[num].getcontent(), this.answerList[num], this.judgeList[num]);
        }
    }
    
    public void printofscore(int num, int value) {
    	int i = 0;
    	for (i = 0; i < Testpaper[num].getrealScore().length; i++) {
    		System.out.printf("%d", Testpaper[num].getrealScore()[gettestpaper()[num].getsitearr()[i]]);
    		if (i < value - 1) {
    			System.out.printf(" ");
    		} else {
    			break;
    		}
    	}
		if (Testpaper[num].getreallength() - value > 0) {
			for (int j = 1; j <= Testpaper[num].getreallength() - value; j++) {
				System.out.printf(" 0");
			}
    	}
    	
    	System.out.printf("~%d\n", Testpaper[num].allrealScore());
    }
}

public class Main{

	public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        answerSheet answersheet = new answerSheet();
        int[] arr;
        int sum = 0;
        int sums = 0;
        int max = 0;
        int value = 2;
        int values = 0;
        int times = 0;
        String[] str = new String[1];

        for (int i = 0;;i++){
            str[i] = scan.nextLine();
            str = Arrays.copyOf(str, str.length + 1);
            //System.out.printf("%s\n", str[i]);
            if (str[i].equals("end"))
                break;
        }

        //System.out.printf("%d", str.length);
        String[][] strs = new String[str.length][];
        
        for (int i = 0; i < str.length; i++) {
            if (str[i].indexOf("#N:") != -1) {
                strs[i] = str[i].split("\\s*#N:\\s*|\\s*#Q:\\s*|\\s*#A:\\s*");
                if (sum < Integer.parseInt(strs[i][1]))
                    sum = Integer.parseInt(strs[i][1]);
            } else if (str[i].indexOf("#T:") != -1) {
                strs[i] = str[i].split("\\s*#T:\\s*|\\s*-\\s*|\\s+");
                sums++;
            } else if (str[i].indexOf("#S:") != -1) {
                strs[i] = str[i].split("\\s*#A:\\s*|\\s*#S:\\s*");
                for (int j = 0; j < strs[i].length; j++) {
                	strs[i][j] = strs[i][j].replaceAll("\\s+$", "");
                }
            } else{
                break;
            }
        }

        arr = new int[sum];
        for (int i = 0; i < arr.length; i++) {
        	arr[i] = -1;
        }
        //System.out.printf("%d", sum);
        answersheet.initsub(sum);
        answersheet.initList(sum);
        answersheet.initpaper(sums);

        for (int i = 0; i < str.length - 1; i++) {
        	if (str[i].indexOf("#N:") != -1){
                answersheet.settextPaper(Integer.parseInt(strs[i][1]) - 1, i, strs[i][2], strs[i][3]);
                arr[values] = Integer.parseInt(strs[i][1]) - 1;
                values++;
            }
        }
        
        for (int i = 0; i < str.length - 1; i++) {
        	if (str[i].indexOf("#T") != -1) {
            	answersheet.initpapers(Integer.parseInt(strs[i][1]) - 1);
            	for (int j = 2; j < 2 + (strs[i].length - 2) / 2; j++) {
            		if (max < Integer.parseInt(strs[i][-2 + 2 * j])) {
            			max = Integer.parseInt(strs[i][-2 + 2 * j]);
            		}
            	}
                answersheet.initarr(Integer.parseInt(strs[i][1]) - 1, max);
            	for (int j = 2; j < 2 + (strs[i].length - 2) / 2; j++) {
                	answersheet.settestpaper(Integer.parseInt(strs[i][1]) - 1, Integer.parseInt(strs[i][-2 + 2 * j]) - 1, Integer.parseInt(strs[i][-1 + 2 * j]));
                	answersheet.setsite(Integer.parseInt(strs[i][1]) - 1, j - 2, Integer.parseInt(strs[i][-2 + 2 * j]) - 1);
            	}
            	answersheet.judgescore(Integer.parseInt(strs[i][1]) - 1);
            }
        }
        
        for (int i = 0; i < str.length - 1; i++) {
            if (str[i].indexOf("#S") != -1 && strs[i].length > 2) {
            	if (Integer.parseInt(strs[i][1]) > answersheet.gettestpaper().length) {
            		System.out.printf("The test paper number does not exist\n");
            		continue;
            	}
            	
            	for (int j = 0; j < strs[i].length - 2; j++) {
                    if (j < answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getreallength()){
            		    answersheet.setanswerList(answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getsitearr()[j], strs[i][value]);
            		    value++;
                    }
            	}
            	
            	for (int j = 0; j < max; j++) {
            		if (j < answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getScore().length && answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getsitearr()[j] != -1) {
	            		if (answersheet.Nonzero(Integer.parseInt(strs[i][1]) - 1, answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getsitearr()[j])) {
	            			answersheet.judgement(answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getsitearr()[j]);
	                		answersheet.printof(answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getsitearr()[j]);
	                		answersheet.scored(Integer.parseInt(strs[i][1]) - 1, answersheet.gettestpaper()[Integer.parseInt(strs[i][1]) - 1].getsitearr()[j]);
	            		}
            		}
                }
            	
            	answersheet.printofscore(Integer.parseInt(strs[i][1]) - 1, value - 2);
            	answersheet.initList(sum);
            	value = 2;
                times++;
            }else if (str[i].indexOf("#S") != -1 && strs[i].length <= 2){
                for (int j = 0; j < answersheet.gettestpaper()[times].getreallength(); j++){
                    answersheet.printof(times);
                }
            	answersheet.printofscore(times, answersheet.gettestpaper()[times].getreallength());
            }
        }
    }
}

測試點結果如圖:

該代碼存在以下問題:
1.缺少控制類,類間耦合性太高
2.不符合單一職責原則
3.主函數加入了大量分割,判斷的內容,使得代碼非常混亂

從這段代碼中學到的:
1.一定要先做好設計再進行代碼的編寫,這個代碼就是因為設計問題,導致最後雖然成功通過了測試點,但是整體結構不符合要求;
2.一定要添加控制類,輸入處理類等,否則在主函數里寫大量的判斷代碼,影響代碼可讀性和可擴展性;
3.在結構設計上一定要合理,如果像這個代碼一樣,用一個實體類與主函數產生關聯關係,會導致類的職責不能做到單一;

踩坑心得
1.由於整個設計出了問題,寫代碼就會很難受,總是寫不出自己想要的效果,所以寫代碼之前一定要做好設計,不做設計直接敲代碼就會走上一條“不歸路”,而且到了後面很難回頭了;
2.主函數里一定要儘量簡潔,不要加入判斷之類的方法在裡面,這樣會導致整個主函數的可讀性非常差,加上程式比較長,可能從後面向前看的時候就發現有些寫過的代碼就看不懂了;
3.類與類之間儘量減少使用關聯關係,這樣會提高類間耦合性,而且不利於數據的傳入傳出;

改進建議
1.增加控制類Control,處理輸入的類Inputment,判斷類Judge等,讓主函數內只有輸入輸出;
2.Answerpaper類和Textpaper類間改為依賴關係,降低耦合性;

7-3 答題判題程式-3

分數 84
困難
作者 蔡軻
單位 南昌航空大學
設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-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。

本題暫不考慮出現多張答卷的信息的情況。

輸入樣例1:
簡單輸入,不含刪除題目信息。例如:

#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:1 20201103 #A:1-5
end

輸出樣例1:
在這裡給出相應的輸出。例如:

alert: full score of test paper1 is not 100 points
1+1=~5~false
20201103 Tom: 0~0

輸入樣例2:
簡單輸入,答卷中含多餘題目信息(忽略不計)。例如:

#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:1 20201103 #A:1-2 #A:2-3
end

輸出樣例3
簡單測試,含刪除題目信息。例如:

alert: full score of test paper1 is not 100 points
1+1=~2~true
20201103 Tom: 5~5

輸入樣例3:
簡單測試,含刪除題目信息。例如:

#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-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end

輸出樣例3:
在這裡給出相應的輸出,第二題由於被刪除,輸出題目失效提示。例如:

alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0

輸入樣例4:
簡單測試,含試卷無效題目的引用信息以及刪除題目信息(由於題目本身無效,忽略)。例如:

#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 3-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end

輸出樣例4:
輸出不存在的題目提示信息。例如:

alert: full score of test paper1 is not 100 points
1+1=~5~false
non-existent question~0
20201103 Tom: 0 0~0

輸入樣例5:
綜合測試,含錯誤格式輸入、有效刪除以及無效題目引用信息。例如:

#N:1 +1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end

輸出樣例5:
在這裡給出相應的輸出。例如:

wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
the question 2 invalid~0
20201103 Tom: 0 0~0

輸入樣例6:
綜合測試,含錯誤格式輸入、有效刪除、無效題目引用信息以及答案沒有輸入的情況。例如:

#N:1 +1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5
#D:N-2
end

輸出樣例6:
答案沒有輸入的優先順序最高。例如:

wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
answer is null
20201103 Tom: 0 0~0

輸入樣例7:
綜合測試,正常輸入,含刪除信息。例如:

#N:2 #Q:2+2= #A:4
#N:1 #Q:1+1= #A:2
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:2-4 #A:1-5
#D:N-2
end

輸出樣例7:
例如:

alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0

輸入樣例8:
綜合測試,無效的試卷引用。例如:

#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:2 20201103 #A:1-5 #A:2-4
end

輸出樣例8:
例如:

alert: full score of test paper1 is not 100 points
The test paper number does not exist

輸入樣例9:
無效的學號引用。例如:

#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201106 Tom
#S:1 20201103 #A:1-5 #A:2-4
end

輸出樣例9:
答案照常輸出,判分時提示錯誤。例如:

alert: full score of test paper1 is not 100 points
1+1=~5~false
20201103 not found

輸入樣例10:
信息可打亂順序輸入:序號不是按大小排列,各類信息交錯輸入。但本題不考慮引用的題目在被引用的信息之後出現的情況(如試卷引用的所有題目應該在試卷信息之前輸入),所有引用的數據應該在被引用的信息之前給出。例如:

#N:3 #Q:中國第一顆原子彈的爆炸時間 #A:1964.10.16
#N:1 #Q:1+1= #A:2
#X:20201103 Tom-20201104 Jack-20201105 Www
#T:1 1-5 3-8
#N:2 #Q:2+2= #A:4
#S:1 20201103 #A:1-5 #A:2-4
end

輸出樣例10:
答案按試卷中的題目順序輸出。例如:

alert: full score of test paper1 is not 100 points
1+1=~5~false
中國第一顆原子彈的爆炸時間~4~false
20201103 Tom: 0 0~0

題目分析
這道題在前一題的基礎上又添加了多答卷,學號姓名輸入,刪除題目等問題,在整體的設計上,應該分為題目類Question,試卷類textPaper,答卷類Answerpaper,判斷類Judge,學生類Student,刪除類Delete,輸入判斷類InputJudge,輸入內容保存類Information類。實際類圖如下:

代碼分析

import java.util.*;
import java.util.Arrays;

class Answerpaper {
	private int[] num = new int[0];
	private int number;
	private String[] studentanswer = new String[0];
	
	public Answerpaper() {
		
	}
	
	public Answerpaper(String[] studentanswer, int number, int[] num) {
		this.studentanswer = studentanswer;
		this.number = number;
		this.num = num;
	}
	
	public void setAnswerpaper(int num, String studentanswer) {
		this.studentanswer = Arrays.copyOf(this.studentanswer, this.studentanswer.length + 1);
		this.studentanswer[this.studentanswer.length - 1] = studentanswer;
		this.num = Arrays.copyOf(this.num, this.num.length + 1);
		this.num[this.num.length - 1] = num;
	}
	
	public String[] getStudentanswer() {
		return studentanswer;
	}
	
	public int getNumber() {
		return number;
	}
	
	public void setNumber(int number) {
		this.number = number;
	}
	
	public int[] getNum() {
		return num;
	}
	
	public void setNum(int[] num) {
		this.num = num;
	}

    public boolean judgement(int n){
        int[] nn = new int[0];
        for (int i = 0; i < num.length; i++){
            nn = Arrays.copyOf(nn, nn.length + 1);
            nn[nn.length - 1] = num[i];
        }
        for (int i = 0; i < nn.length; i++){
            if (nn[i] == n){
                return true;
            }
        }
        return false;
    }
}

class Delete {
	public void Deletequestion(int num, Textpaper textpaper) {
		for (int i = 0; i < textpaper.getQuestion().length; i++) {
			if (textpaper.getQuestion()[i].getNum() == num) {
				textpaper.getQuestion()[i].setExist(false);
				break;
			}
		}
	}
}

class Information {
	private String[] NQA = new String[0];
	private String[] T = new String[0];
	private String[] X = new String[0];
	private String[] SA = new String[0];
	private String[] D = new String[0];
	
	public Information() {
		
	}

	public Information(String[] nQA, String[] t, String[] x, String[] sA, String[] d) {
		NQA = nQA;
		T = t;
		X = x;
		SA = sA;
		D = d;
	}
	
	public String[] getNQA() {
		return NQA;
	}

	public void setNQA(String nQA) {
		NQA = Arrays.copyOf(NQA, NQA.length + 1);
		NQA[NQA.length - 1] = nQA;
	}

	public String[] getT() {
		return T;
	}

	public void setT(String t) {
		T = Arrays.copyOf(T, T.length + 1);
		T[T.length - 1] = t;
	}

	public String[] getX() {
		return X;
	}

	public void setX(String x) {
		X = Arrays.copyOf(X, X.length + 1);
		X[X.length - 1] = x;
	}

	public String[] getSA() {
		return SA;
	}

	public void setSA(String sA) {
		SA = Arrays.copyOf(SA, SA.length + 1);
		SA[SA.length - 1] = sA;
	}

	public String[] getD() {
		return D;
	}

	public void setD(String d) {
		D = Arrays.copyOf(D, D.length + 1);
		D[D.length - 1] = d;
	}
	
	public boolean judgement(int n) {
		int[] nn = new int[0];
		for (int i = 0; i < NQA.length; i++) {
			String[] str = NQA[i].split("\\s*#N:\\s*|\\s*#Q:\\s*|\\s*#A:\\s*");
			nn = Arrays.copyOf(nn, nn.length + 1);
			nn[nn.length - 1] = Integer.parseInt(str[1]);
		}
		for (int i = 0; i < nn.length; i++) {
			if (nn[i] == n)
				return true;
		}
		return false;
	}
}

class inputJudge {
	public boolean inputjudge(String str) {
		if (str.matches("#N:\\s*(\\d+)\\s*#Q:\\s*(.*?)\\s*#A:\\s*(.*?)\\s*"))
			return true;
		else if (str.matches("^#T:( )*\\d+( )*((\\d+(( )*)-(( )*)\\d+( )*)+)$"))
			return true;
		else if (str.matches("^#X:\\s*\\d+\\s(\\w+)+(?:-\\d+\\s\\w+)*$"))
			return true;
		else if (str.matches("^#S:( )*\\d+( )*\\d+\\s*(.*?)$"))
			return true;
		else if (str.matches("^#D:\\s*N\\s*-\\s*\\d+( )*$"))
			return true;
		else 
			return false;
	}
}

class Judge {
	public void judgeAnswer(Textpaper textpaper, Answerpaper answerpaper, Student student, String str) {
		int value = 0;
		for (int i = 0; i < textpaper.getQuestion().length; i++) {
			if (!answerpaper.judgement(i + 1)){
                System.out.printf("answer is null\n");
                textpaper.getQuestion()[i].setScore(0);
                continue;
            } else if (textpaper.getQuestion()[i].getExist() && textpaper.getQuestion()[i].getContent().equals("none")) {
				value++;
				System.out.printf("non-existent question~0\n");
				textpaper.getQuestion()[i].setScore(0);
			}
			for (int j = 0; j < answerpaper.getNum().length; j++) {
				if (answerpaper.getNum()[j] - 1 >= textpaper.getQuestion().length) {
					continue;
				}
				if (answerpaper.getNum()[j] == i + 1) {
					if (textpaper.getQuestion()[i].getStandardanswer().equals(answerpaper.getStudentanswer()[j]) && textpaper.getQuestion()[i].getExist()) {
						value++;
						System.out.printf("%s~%s~true\n", textpaper.getQuestion()[i].getContent(), answerpaper.getStudentanswer()[j]);
					} else if (!textpaper.getQuestion()[i].getStandardanswer().equals(answerpaper.getStudentanswer()[j]) && textpaper.getQuestion()[i].getExist() && !textpaper.getQuestion()[i].getContent().equals("none")) {
						value++;
						System.out.printf("%s~%s~false\n", textpaper.getQuestion()[i].getContent(), answerpaper.getStudentanswer()[j]);
						textpaper.getQuestion()[i].setScore(0);
					} else if (!textpaper.getQuestion()[i].getExist()) {
						value++;
						System.out.printf("the question %d invalid~0\n", textpaper.getQuestion()[i].getNum());
						textpaper.getQuestion()[i].setScore(0);
					} 
					break;
				}
                if (j == answerpaper.getNum().length - 1) {
					textpaper.getQuestion()[i].setScore(0);
				}
			}
		}
		for (int i = 0; i < student.getSid().length; i++) {
			int allscore = 0;
            if (!student.judgement(str)){
                System.out.printf("%s not found", str);
                break;
            }
			if (str.equals(student.getSid()[i])) {
				System.out.printf("%s %s:", student.getSid()[i], student.getName()[i]);
				for (int j = 0; j < textpaper.getQuestion().length; j++) {
					allscore += textpaper.getQuestion()[j].getScore();
					System.out.printf(" %d", textpaper.getQuestion()[j].getScore());
				}
				System.out.printf("~%d", allscore);
				System.out.printf("\n");
				break;
			}
		}
	}
}

class Textpaper {
	private int number;
	private Question[] question = new Question[0];

	public Textpaper() {
		
	}

	public Textpaper(Question[] question, int number) {
		this.question = question;
		this.number = number;
	}

	public Question[] getQuestion() {
		return question;
	}

	public void setQuestion(int num, String content, String standardanswer, int score) {
		this.question = Arrays.copyOf(this.question, this.question.length + 1);
		this.question[this.question.length - 1] = new Question();
		this.question[this.question.length - 1].setNum(num);
		this.question[this.question.length - 1].setContent(content);
		this.question[this.question.length - 1].setStandardanswer(standardanswer);
		this.question[this.question.length - 1].setScore(score);
	}
	
	public int getNumber() {
		return number;
	}
	
	public void setNumber(int number) {
		this.number = number;
	}
	
	public void judgeAllScore() {
		int sum = 0;
		for (int i = 0; i < question.length; i++) {
			sum += question[i].getScore();
		}
		if (sum != 100) {
			System.out.printf("alert: full score of test paper%d is not 100 points\n", this.number);
		}
	}

    public boolean judgement(int n){
        int[] nn = new int[0];
        for (int i = 0; i < question.length; i++){
            nn = Arrays.copyOf(nn, nn.length + 1);
            nn[nn.length - 1] = question[i].getNum();
        }
        for (int i = 0; i < nn.length; i++){
            if (nn[i] == n){
                return true;
            }
        }
        return false;
    }
}


class Student {
	private String[] name = new String[0];
	private String[] sid = new String[0];
	
	public Student() {
		
	}	
	
	public Student(String[] name, String[] sid) {
		this.name = name;
		this.sid = sid;
	}

	public String[] getName() {
		return name;
	}

	public void setName(String[] name) {
		this.name = name;
	}

	public String[] getSid() {
		return sid;
	}

	public void setSid(String[] sid) {
		this.sid = sid;
	}
	
	public void setStudent(String sid, String name) {
		this.sid = Arrays.copyOf(this.sid, this.sid.length + 1);
		this.sid[this.sid.length - 1] = sid;
		this.name = Arrays.copyOf(this.name, this.name.length + 1);
		this.name[this.name.length - 1] = name; 
	}

    public boolean judgement(String str) {
		String[] strs = new String[0];
		for (int i = 0; i < sid.length; i++) {
			strs = Arrays.copyOf(strs, strs.length + 1);
			strs[strs.length - 1] = sid[i];
		}
		for (int i = 0; i < strs.length; i++) {
			if (strs[i].equals(str)) {
				return true;
			}
		}
		return false;
	}
}

class Question {
	private int num;
	private String content;
	private String standardanswer;
	private int score;
	private boolean exist = true;

	public Question() {
		
	}

	public Question(int num, String content, String standardanswer, int score, boolean exist) {
		this.num = num;
		this.content = content;
		this.standardanswer = standardanswer;
		this.score = score;
		this.exist = exist;
	}

	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 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 boolean getExist() {
		return exist;
	}
	
	public void setExist(boolean exist) {
		this.exist = exist;
	}
}

public class Main {
	public static void main(String[] args) {
		int[] value = new int[0];
		Scanner scan = new Scanner(System.in);
		Information information = new Information();
		inputJudge inputjudge = new inputJudge();
		Answerpaper[] answerpaper = new Answerpaper[0];
		Textpaper[] textpaper = new Textpaper[0];
		Student student = new Student();
		Delete delete = new Delete();
		Judge judge = new Judge();
		while (true) {
			String str = scan.nextLine();
			if (str.equals("end")) {
				break;
			}
			if (inputjudge.inputjudge(str)) {
				if (str.matches("#N:\\s*(\\d+)\\s*#Q:\\s*(.*?)\\s*#A:\\s*(.*?)\\s*"))
					information.setNQA(str);
				else if (str.matches("^#T:( )*\\d+( )*((\\d+(( )*)-(( )*)\\d+( )*)+)$"))
					information.setT(str);
				else if (str.matches("^#S:( )*\\d+( )*\\d+\\s*(.*?)$"))
					information.setSA(str);
				else if (str.matches("^#X:\\s*\\d+\\s(\\w+)+(?:-\\d+\\s\\w+)*$"))
					information.setX(str);
				else if (str.matches("^#D:\\s*N\\s*-\\s*\\d+( )*$"))
					information.setD(str);
			}
			else {
				System.out.printf("wrong format:%s\n", str);
			}
		}
		for (int i = 0; i < information.getT().length; i++) {
			String[] strs = information.getT()[i].split("\\s*#T:\\s*|\\s*-\\s*|\\s+");
			textpaper = Arrays.copyOf(textpaper, textpaper.length + 1);
			textpaper[i] = new Textpaper();
			textpaper[i].setNumber(Integer.parseInt(strs[1]));
			for (int k = 0; k < (strs.length - 2) / 2; k++) {
                if (information.getNQA().length != 0){
    				for (int j = 0; j < information.getNQA().length; j++) {
    					String[] str = information.getNQA()[j].split("\\s*#N:\\s*|\\s*#Q:\\s*|\\s*#A:\\s*");
    					if (str.length == 4){
                            for (int t = 0; t < str.length; t++) {
        						str[t] = str[t].trim();
        					}
                        } else {
                            str = Arrays.copyOf(str, str.length + 1);
                            str[str.length - 1] = "";
                        }
    					if (strs[2 + k * 2].equals(str[1])) {
    						if (str.length == 4) {
    							textpaper[i].setQuestion(Integer.parseInt(str[1]), str[2], str[3], Integer.parseInt(strs[2 + k * 2 + 1]));
    							break;
    						} else {
    							textpaper[i].setQuestion(Integer.parseInt(str[1]), str[2], " ", Integer.parseInt(strs[2 + k * 2 + 1]));
    							break;
    						}
    					} else if (!strs[2 + k * 2].equals(str[1]) && !information.judgement(Integer.parseInt(strs[2 + k * 2]))) {
    						textpaper[i].setQuestion(Integer.parseInt(strs[2 + k * 2]), "none", "none", 0);
    					    break;
                        } 
    				}
                } else {
                    textpaper[i].setQuestion(Integer.parseInt(strs[2 + k * 2]), "none", "none", 0);
                }
			}
			textpaper[i].judgeAllScore();
		}
		for (int i = 0; i < information.getD().length; i++) {
			String[] str = information.getD()[i].split("\\s*#D:\\s*N-");
			for (int j = 0; j < information.getT().length; j++) {
				delete.Deletequestion(Integer.parseInt(str[1]), textpaper[j]);
			}
		}
		for (int i = 0; i < information.getX().length; i++) {
			String[] str = information.getX()[i].split("\\s*#X:\\s*|\\s+|\\s*-\\s*");
			for (int k = 0; k < (str.length - 1) / 2; k++) {
				student.setStudent(str[1 + k * 2], str[2 + k * 2]);
			}
		}
		for (int i = 0; i < information.getSA().length; i++) {
			answerpaper = Arrays.copyOf(answerpaper, answerpaper.length + 1);
			answerpaper[i] = new Answerpaper();
			String p = information.getSA()[i];
	        p = p.replaceAll("#S:", "");
	        p = p.replaceAll("#A:", "");
	        String[] s1 = p.split("\\s+");
	        answerpaper[i].setNumber(Integer.parseInt(s1[0]));
	        String s = information.getSA()[i].replaceAll("^#S:\\d+ \\d{8} ","");
	        information.getSA()[i] = information.getSA()[i].substring(1, information.getSA()[i].length());
	        s = s.replaceAll("#A", "");
	        String S[] = s.split(":");
	        for(int j = 0; j < S.length; j++){
	            String ss[] = S[j].split("-");
	            if(ss.length == 2){
	                if(ss[1].matches("\\s+") && ss[1] != " "){
	                	answerpaper[i].setAnswerpaper(Integer.parseInt(ss[0]), "");
	                    continue;
	                }
	                if(i != S.length - 1){
	                    if(ss[1].length() == 1 && ss[1].charAt(ss[1].length() - 1) == ' '){
	                    	answerpaper[i].setAnswerpaper(Integer.parseInt(ss[0]), "");
	                        continue;
	                    }
	                }
	                while(ss[1].charAt(ss[1].length() - 1) == ' '){
	                        ss[1] = ss[1].substring(0,ss[1].length() - 1);
	                }
	                while(ss[1].charAt(0) == ' '){
	                    ss[1] = ss[1].substring(1,ss[1].length());
	                }
	                answerpaper[i].setAnswerpaper(Integer.parseInt(ss[0]), ss[1]);
	            }
	        }
		}
        for (int i = 0; i < information.getSA().length; i++) {
            String[] str = information.getSA()[i].split("\\s*#S:\\s*|\\s*#A:\\s*|\\s+|\\s*-\\s*");
            int arr[] = new int[0];
            for (int j = 0; j < textpaper.length; j++) {
            	arr = Arrays.copyOf(arr, arr.length + 1);
            	arr[arr.length - 1] = textpaper[j].getNumber();
            }
            for (int j = 0; j < arr.length; j++) {
            	if (arr[j] == answerpaper[i].getNumber()) {
            		for (int k = 0; k < textpaper.length; k++) {
                        if (answerpaper[i].getNumber() == textpaper[k].getNumber()){
                            judge.judgeAnswer(textpaper[k], answerpaper[i], student, str[1]);
                            break;
                        } 
                    }
            		break;
            	}
            	if (j == arr.length - 1) {
            		System.out.printf("The test paper number does not exist\n");
            		break;
            	}
            }
        }
        if (information.getT().length == 0) {
        	for (int i = 0; i < answerpaper.length; i++) {
        		System.out.printf("The test paper number does not exist\n");
        	}
        }
    }
}

測試點結果如圖:

該代碼存在的問題:
1.雖然設計了很多類,但最後的判斷和輸出放在了一個類裡面,還是沒有實現單一職責原則;
2.主函數里還有大量有關正則表達式匹配的代碼,這段代碼應該專門放在一個類裡面處理;
3.代碼不能判斷題目在試卷後面輸入的情況,雖然沒有這測試點,但這是一個bug;
4.正則表達式存在問題,有些情況不能判斷,但是沒有相關的測試點;

從這段代碼中學到的:
1.一定要多設計類,儘量保證他們是單一職責的;
2.判斷跟輸出的類要分開寫,不然會出現輸出提示信息順序的問題
3.要多和同學交流,這道題的難度明顯高於前面兩題,但是經過晚自習組織討論,思路非常清晰,最後也是成功編寫出程式;

踩坑心得
1.開始的時候樣例全部能通過,但是其他測試點幾乎都不能過,因為判斷的類與輸出的類是同一個,導致輸出的順序出現問題;
2.要分清題目編號和題目在試卷中的編號,比如題目編號是1,有可能在試卷中的編號是2;
3.在前面正則表達式分割的階段,要註意輸入為空和輸入非法時候的情況,不做處理會導致編譯器非零返回錯誤;

改進建議
1.增加一個輸出類Print,讓判斷跟輸入分離,就不會在輸出提示信息的時候出錯了。
2.減少主函數內的判斷代碼,用其他類的方法代替主方法進行判斷;
3.減少使用關聯,降低類間耦合性

總結

通過這三次PTA大作業,我深刻體會到面向對象程式設計的難點——設計。在寫代碼之前,一個良好的設計能讓人事半功倍,而不好的設計會讓人事倍功半。對於類的設計這一塊,單一職責原則是我還要繼續努力學習的,從第三次代碼來看,目前我已經形成了一定的單一職責原則的思想觀念,但是對此的執行能力還有待提升。因此,在今後的學習中,對類的設計思想是學習的中點目標。
在今後的PTA作業里,還要鍛煉自己的語法水平,提高類設計的合理性與可復用性,力爭做到國家級一流課的編碼要求。
在編碼規範方面,我也還要繼續努力,要消除意義不明確的變數,都用變數意義相關的單詞進行書寫,這樣才能符合編碼規範,提高代碼的可讀性。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 主題搗鼓日記 sakura版本(YYDS) 主要框架都沒怎麼動,功能挺完整的。但是如果要DIY還是得自己把代碼捋一遍,不然從哪改起都不知道,註釋不能說完全沒用。。。 搗鼓了兩天兩夜,還是有很多細節沒改好,main.js翻了四五遍,看評論區發現諸多細節還要改CSS文件,太難了。。前端都忘得差不多了,趕 ...
  • 一、題目及運行環境 1.小組成員 2252331 與 2252336 2.題目 小學老師要每周給同學出300道四則運算練習題。 這個程式有很多種實現方式: C/C++ C#/VB.net/Java Excel Unix Shell Emacs/Powershell/Vbscript Perl Pyt ...
  • 什麼是介面重覆提交? 介面重覆提交指的是在網路通信中,同一個請求被客戶端多次發送到伺服器端的情況。這種情況可能由於多種原因導致,例如用戶在等待期間多次點擊提交按鈕、網路超時後客戶端重新發送請求、客戶端發送的請求在網路傳輸過程中出現重覆等。 介面重覆提交可能會導致多種問題,當伺服器收到重覆請求時,可能 ...
  • 其他章節請看: vue3 快速入門 系列 他API 前面我們已經學習了 vue3 的一些基礎知識,本篇將繼續講解一些常用的其他api,以及較完整的分析vue2 和 vue3 的改變。 淺層響應式數據 shallowRef shallow 中文:“淺層的” shallowRef:淺的 ref()。 先 ...
  • 零代碼指的是藉助VuePress 通過簡單配置,幫助我們生成靜態網站。 零成本指的是藉助GitHub Pages 或者Gitee Pages部署網站,讓互聯網上的小伙伴能訪問到它 ...
  • XQuery 是 XML 數據的查詢語言,類似於 SQL 是資料庫的查詢語言。它被設計用於查詢 XML 數據。 XQuery 示例 for $x in doc("books.xml")/bookstore/book where $x/price > 30 order by $x/title retu ...
  • 一、代碼分割 一個大型前端應用,如果所有代碼都放在單一文件,體積會特別大,下載時間長,白屏時間久,用戶體驗差。 代碼分割是一種有效的優化方式。提前把代碼切分為多個小塊,只下載當前必需的部分,用到哪塊下載哪塊。就像吃自助餐一樣,吃多少拿多少。 早期的代碼分割一般通過 webpack 實現。隨著 ES6 ...
  • splice在英語中的意思是拼接,在實際的代碼使用中,splice就在數組中起到了一個拼接的作用 使用方法 splice(x,y,a,b,c,...) 其中x、y為數字,a、b、c為新添加的項,意思是從數組的第x項開始刪除y項,併在其中添加a、b、c...,其中x、y必填,abc可不填 圖像理解 現 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...