對題目集1~3的總結

时坠發表於2024-04-21

1.前言


  • 這三次題目集主要考察對字串分割,判定輸入格式,提取有用資訊,最後進行對資訊的處理。
  • 題目的要求及資訊條件較多,在寫程式碼時很容易缺漏一些特殊情況,考慮不周。
  • 對我而言並不簡單,有很多測試點沒過。

2.設計與分析


答題判題程式-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

點選檢視程式碼
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n,i;
        n=sc.nextInt();
        sc.nextLine();
        Answer A = new Answer(n);
        for(i=0;i<n;i++)
        {
            String x=sc.nextLine();
            String[] y=x.split("#[ANQ]:");
            Question z = new Question(Integer.parseInt(y[1].trim()),y[2].trim(),y[3].trim());
            A.x[Integer.parseInt(y[1].trim())-1]=z;
        }
        for(i=0;i<n;i++)
        {
            String x=sc.next();
            String[] y=x.split("#[A]:");
            A.answer[i]=y[1].trim();
        }
        A.showAnswer();
        A.showOutcome();
    }
}
class Answer{
    int n;
    String[] answer;
    Question[] x;

    public Answer(int n){
        this.n=n;
        answer = new String[n];
        x = new Question[n];
        for(int i=0;i<n;i++)
            x[i]= new Question();
    }

    public void showAnswer(){
        for(int j=0;j<n;j++)
            System.out.println(x[j].question + "~" + this.answer[j]);
    }
    public void showOutcome(){
        for(int j=0;j<n;j++)
        {
            if(this.answer[j].equals(x[j].answer))
                System.out.print("true");
            else System.out.print("false");
            if(j!=n-1)
                System.out.print(" ");
        }
    }
}
class Question{
    int number;
    String answer,question;

    public Question(int a,String b,String c){
        number=a;
        question=b;
        answer=c;
    }
    public Question(){
        
    }
}

image

  • 第一次題目相對簡單,我透過split對輸入的字串進行分割,因為已知問題的數量,且不存在亂序輸入,直接迴圈n次,將問題資訊全部提取儲存,在最後輸入答案時直接判定即可。

答題判題程式-2

點選檢視題目資訊
設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-1基礎上增補或者修改的內容。

要求輸入題目資訊、試卷資訊和答題資訊,根據輸入題目資訊中的標準答案判斷答題的結果。

輸入格式:

程式輸入資訊分三種,三種資訊可能會打亂順序混合輸入:

1、題目資訊

   一行為一道題,可輸入多行資料(多道題)。

   格式:"#N:"+題目編號+" "+"#Q:"+題目內容+" "#A:"+標準答案

格式約束:

    1、題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
    2、允許題目編號有缺失,例如:所有輸入的題號為1、2、5,缺少其中的3號題。此種情況視為正常。
   樣例:#N:1 #Q:1+1= #A:2

         #N:2 #Q:2+2= #A:4

2、試卷資訊

一行為一張試卷,可輸入多行資料(多張卷)。

格式:"#T:"+試卷號+" "+題目編號+"-"+題目分值

     題目編號應與題目資訊中的編號對應。

     一行資訊中可有多項題目編號與分值。
樣例:#T:1 3-5 4-8 5-2

3、答卷資訊

    答卷資訊按行輸入,每一行為一張答卷的答案,每組答案包含某個試卷資訊中的題目的解題答案,答案的順序與試卷資訊中的題目順序相對應。

   格式:"#S:"+試卷號+" "+"#A:"+答案內容

   格式約束:答案數量可以不等於試卷資訊中題目的數量,沒有答案的題目計0分,多餘的答案直接忽略,答案之間以英文空格分隔。

   樣例:#S:1 #A:5 #A:22

       1是試卷號 

       5是1號試卷的順序第1題的題目答案

       22是1號試卷的順序第2題的題目答案
   答題資訊以一行"end"標記結束,"end"之後的資訊忽略。

輸出格式:

1、試卷總分警示

該部分僅當一張試卷的總分分值不等於100分時作提示之用,試卷依然屬於正常試卷,可用於後面的答題。如果總分等於100分,該部分忽略,不輸出。

   格式:"alert: full score of test paper"+試卷號+" is not 100 points"

   樣例:alert: full score of test paper2 is not 100 points

2、答卷資訊

   一行為一道題的答題資訊,根據試卷的題目的數量輸出多行資料。

   格式:題目內容+"~"+答案++"~"+判題結果(true/false)

約束:如果輸入的答案資訊少於試卷的題目數量,答案的題目要輸"answer is null"   

樣例:3+2=~5~true

         4+6=~22~false.

      answer is null
3、判分資訊

   判分資訊為一行資料,是一條答題記錄所對應試卷的每道小題的計分以及總分,計分輸出的先後順序與題目題號相對應。

   格式:題目得分+" "+....+題目得分+"~"+總分

   格式約束:

 1、沒有輸入答案的題目計0分

 2、判題資訊的順序與輸入答題資訊中的順序相同
   樣例:5 8 0~13

根據輸入的答卷的數量以上2、3項答卷資訊與判分資訊將重複輸出。

4、提示錯誤的試卷號

如果答案資訊中試卷的編號找不到,則輸出”the test paper number does not exist”,參見樣例9。


設計建議:

參考答題判題程式-1,建議增加答題類,類的內容以及類之間的關聯自行設計。

輸入樣例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
點選檢視程式碼
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String x="";
        int n,i,j;
        x=sc.nextLine();
        List<Question> question= new ArrayList<>();
        List<Test> test= new ArrayList<>();
        List<Answer> answer= new ArrayList<>();
        while(!x.equals("end"))
        {
            if(x.startsWith("#N"))
            {
                String[] y=x.split("#[ANQ]:");
                Question z = new Question(Integer.parseInt(y[1].trim()),y[2].trim(),y[3].trim());
                question.add(z);
            }
            if(x.startsWith("#T"))
            {
                int s=0;
                String[] y=x.split(" ");
                Test tt = new Test(y[0].charAt(3)-'0');
                for(i=1;i<y.length;i++)
                {
                    Score ts = new Score(y[i]);
                    tt.score.add(ts);
                    for(j=0;j<question.size();j++)
                    {
                        if(question.get(j).number==ts.questionNum)
                            tt.question.add(question.get(j));
                    }
                }
                tt.allScore();
                test.add(tt);
            }
            if(x.startsWith("#S"))
            {
                Answer t = new Answer(x);
                if(t.testNum<=test.size())
                    t.test=test.get(t.testNum-1);//未排序!!!
                else 
                    t.test = new Test(0);
                answer.add(t);
            }
            x=sc.nextLine();
        }
        for(i=0;i<answer.size();i++)
        {
            if(answer.get(i).test.number==0)
                System.out.println("The test paper number does not exist");
            else answer.get(i).showScore();
        }
    }
}
class Test{
    int number;
    List<Question> question;
    List<Score> score;

    public Test(int n){
        number=n;
        question = new ArrayList<>();
        score= new ArrayList<>();
    }

    public void allScore(){
        int i,s=0;
        for(i=0;i<score.size();i++)
            s+=score.get(i).score;
        if(s!=100)
            System.out.println("alert: full score of test paper"+number+" is not 100 points");
    }
}
class Answer{
    int testNum;
    String[] answer;
    Test test;

    public Answer(String str){
        answer = str.split("\\s*#[SA]:");//0="",1=s,2=a
        testNum=Integer.parseInt(answer[1].trim());
        test = new Test(testNum);
    }
    
    public void showScore(){
        int i,j,s=0,f;
        for(i=0;i<test.question.size();i++)
        {
            String t = "false";
            if(i+2>=answer.length)
                System.out.println("answer is null");
            else
            {
                if(test.question.get(i).answer.equals(answer[i+2]))
                    t= "true";
                System.out.println(test.question.get(i).question+"~"+answer[i+2]+"~"+t);
            }
        }
        for(i=0;i<test.question.size();i++)
        {
            f=0;
            if(i+2<answer.length)
                if(test.question.get(i).answer.equals(answer[i+2]))
                {
                    System.out.print(test.score.get(i).score);
                    s+=test.score.get(i).score;f=1;
                }
            if(f==0)
                System.out.print("0");
            if(i==test.question.size()-1)
                System.out.print("~");
            else System.out.print(" ");
            
        }
        System.out.println(s);
    }
}
class Question{
    int number;
    String answer,question;

    public Question(int a,String b,String c){
        number=a;
        question=b;
        answer=c;
    }
    public Question(){
        
    }
}
class Score{
    int questionNum;
    int score;

    public Score(String x){
        String[] y = x.split("-");
        questionNum=Integer.parseInt(y[0].trim());
        score= Integer.parseInt(y[1].trim());
    }
}

image

  • 第二次題目存在亂序輸入,而且不再有問題總數的提示,只能判斷輸入是否為end來判定結束。這比第一次題目難了不少,而且我在第一次題目中設計過於簡單,不適合本次題目,於是我只能推翻重寫。

  • 我設計用3個ArrayList儲存 題目資訊、試卷資訊、答卷資訊,由於3種資訊的輸入格式不同,我只需判斷開頭的輸入格式即可判斷是哪種資訊(在做此題時,我還未考慮到錯誤輸入的情況)。當有問題資訊輸入時,存入question陣列;當有試卷資訊輸入時,將對應問題提取至試卷中,再存入test陣列;當有答卷資訊輸入時,將對應試卷提取至答卷中,再存入answer陣列。最後對answer陣列中每個元素進行結果判定及輸出即可。


答題判題程式-3

點選檢視題目資訊
設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-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
點選檢視程式碼
import java.util.*;
import java.util.regex.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String x="";
        int n,i,j,k;
        x=sc.nextLine();
        List<Test> test= new ArrayList<>();
        List<Integer> delete= new ArrayList<>();
        List<Student> student= new ArrayList<>();
        List<StuAnswer> answer= new ArrayList<>();
        List<Question> question= new ArrayList<>();
        while(!x.equals("end"))//正則未判定所有出現空格的可能
        {
            int f=0;
            //加入題目
            Pattern p = Pattern.compile("\\s*#N:(\\d+)\\s*#Q:(.*)#A:(.*)");
            Matcher m = p.matcher(x);
            if(f==0&&m.find())//#N
            {
                //System.out.println("wrong format:"+1);
                f=1;
                Question z = new Question(Integer.parseInt(m.group(1)),m.group(2),m.group(3));
                question.add(z);
            }
            //加入試卷
            p=Pattern.compile("\\s*#T:(\\d)+\\s*((\\d+-\\d+\\s*)*)$");
            //1.試卷號 2.剩餘內容
            m = p.matcher(x);
            if(f==0&&m.find())//#T
            {
                //System.out.println("wrong format:"+2);
                int s=0;f=1;
                Test tt = new Test(Integer.parseInt(m.group(1).trim()));
                String[] y = m.group(2).split(" ");
                for(i=0;i<y.length;i++)
                {
                    int f1=0;
                    Score ts = new Score(y[i]);
                    tt.score.add(ts);
                    for(j=0;j<question.size();j++)
                        if(question.get(j).number==ts.questionNum)
                        {
                            tt.question.add(question.get(j));
                            f1=1;
                        }
                    if(f1==0)
                    {
                        Question tq = new Question();
                        tt.question.add(tq);
                    }
                }
                test.add(tt);
            }
            //加入答卷
            p=Pattern.compile("\\s*#S:(\\d+)\\s*(\\d+)\\s*((#A:\\d+-\\w*\\s*)*)$");
            //1.試卷編號,2.id,3.題號.答案
            m = p.matcher(x);
            if(f==0&&m.find())//#S 未修改,輸入可以選擇題號
            {
                f=1;
                //System.out.println("wrong format:"+3);
                StuAnswer t = new StuAnswer(m.group(1),m.group(2));
                String[] y = m.group(3).split("#A:");
                for(i=1;i<y.length;i++)
                {
                    Answer ta = new Answer(y[i]);
                    t.answer.add(ta);
                }
                answer.add(t);
            }
            //刪除題目
            p=Pattern.compile("\\s*#D:N-(\\d+)");
            m = p.matcher(x);
            if(f==0&&m.find())//#D
            {
                f=1;
                //System.out.println("wrong format:"+4);
                int t = Integer.parseInt(m.group(1).trim());
                delete.add(t);
                // for(i=0;t!=-1&&i<question.size();i++)
                //     if(question.get(i).number==t)
                //     {
                //         question.get(i).state=0;
                //         t=-1;
                //     }
            }
            //加入學生
            p=Pattern.compile("\\s*#X:(\\d+)\\s+(\\w+)((-\\d+\\s+\\w+)*)$");
            //1.2.學生1  3.剩餘內容
            m = p.matcher(x);
            if(f==0&&m.find())//#X
            {
                f=1;
                //System.out.println("wrong format:"+5);
                Student t = new Student(m.group(1),m.group(2));
                student.add(t);
                String[] y = m.group(3).split("-");//0.為空 
                for(i=1;i<y.length;i++)
                {
                    String[] z = y[i].split(" ");
                    Student tem = new Student(z[0],z[1]);
                    student.add(tem);
                }
            }
            
            if(f==0)
                System.out.println("wrong format:"+x);
            x=sc.nextLine();
        }
        // //試卷判定
        for(i=0;i<test.size();i++)
        {
            int s=0;
            for(j=0;j<delete.size();j++)
                test.get(i).deleteQuestion(delete.get(j));
            if(test.get(i).addScore()!=100)
                System.out.println("alert: full score of test paper"+test.get(i).number+" is not 100 points");
        }
        //答卷判定
        for(i=0;i<answer.size();i++)
        {
            int f=-1;
            StuAnswer t = answer.get(i);
            for(j=0;f==-1&&j<test.size();j++)
                if(t.testNum==test.get(j).number)
                    f=j;
            if(f!=-1)
            {
                t.test=test.get(f);
                t.showEachScore();
                for(j=0;f!=-1&&j<student.size();j++)
                {
                    if(t.id.equals(student.get(j).id))
                    {
                        System.out.print(t.id+" "+student.get(j).name+": ");
                        t.showAllScore();
                        f=-1;
                    }
                }
                if(f!=-1)
                    System.out.println(t.id+" not found");
            }
            else System.out.println("The test paper number does not exist");
        }
    }
}
class Answer{
    int questionNum;
    String answer;

    public Answer(String x){
        String[] y = x.split("-");
        questionNum=Integer.parseInt(y[0].trim());
        answer=y[1].trim();
    }
}
class StuAnswer{
    int testNum;
    String id;
    List<Answer> answer;
    Test test;

    public StuAnswer(String a,String b){
        answer = new ArrayList<>();
        test = new Test(testNum);
        testNum=Integer.parseInt(a.trim());
        id=b.trim();
    }
    public void showEachScore(){
        int i,j,f;
        for(i=0;i<test.question.size();i++)
        {
            String t = "false";f=-1;
            Question tq = test.question.get(i);
            for(j=0;j<answer.size();j++)
                if(answer.get(j).questionNum==i+1)
                {
                    f=j;
                    break;
                }
            if(f==-1)
                    System.out.println("answer is null");
            else if(tq.number==-1)
                System.out.println("non-existent question~0");
            else if(test.score.get(i).score==-1)
                System.out.println("the question "+tq.number+" invalid~0");
            else
            {
                if(tq.answer.equals(answer.get(j).answer))
                {
                    t= "true";
                    tq.state=2;
                }
                System.out.println(test.question.get(i).question+"~"+answer.get(f).answer+"~"+t);
            }
        }
    }
    //總成績顯示
    public void showAllScore(){
        int i,j,s=0;
        for(i=0;i<test.question.size();i++)
        {
            Question tq = test.question.get(i);
            if(tq.state==2)
            {
                System.out.print(test.score.get(i).score);
                s+=test.score.get(i).score;
            }
            else System.out.print("0");
            if(i==test.question.size()-1)
                System.out.print("~");
            else System.out.print(" ");
        }
        System.out.println(s);
    }
}
class Student{
    String id;
    String name;

    Student(String a,String b){
        id=a.trim();
        name=b.trim();
    }
}
class Test{
    int number;
    List<Question> question;
    List<Score> score;

    public Test(int n){
        number=n;
        question = new ArrayList<>();
        score= new ArrayList<>();
    }

    public int addScore(){
        int i,s=0;
        for(i=0;i<score.size();i++)
            s+=score.get(i).score;
        return s;
    }
    public void deleteQuestion(int a){
        for(int i=0;i<question.size();i++)
            if(a==question.get(i).number)
                score.get(i).score=-1;
    }
}
class Question{
    int number;
    int state;
    String answer,question;

    public Question(int a,String b,String c){
        number=a;
        question=b.trim();
        answer=c.trim();
        state=1;
    }
    public Question(){
        number=-1;
        question="";
        answer="";
        state=1;
    }
}
class Score{
    int questionNum;
    int score;

    public Score(String x){
        String[] y = x.split("-");
        questionNum=Integer.parseInt(y[0].trim());
        score= Integer.parseInt(y[1].trim());
    }
}

image

  • 第三次題目要求再次提升,我發現我在第二次題目中對輸入的判定在此次題目中完全不適用,於是之保留了類的基礎設計,主體全部重新再寫。

  • 原始碼分析如下

  1. 我先利用正規表示式判斷輸入資訊是否符合標準,若符合某種輸入標準,就進入對應的操作,若不符合所以輸入標準,則為輸入格式錯誤。

  2. 找到對應的輸入資訊後,提取有用資訊並存入對應陣列中。

  3. 所有資訊輸入完畢後,先對試卷進行判定;再判定答卷,將對應的試卷資訊存入答卷中,最後對答卷進行結果判定。


3.踩坑心得


1. 這三次題目,每次我都考慮不周,程式碼僅適用於本次題目,導致我每次都基本是重新寫。日後在設計過程中,應廣泛考慮實際可能存在的情況,讓程式碼的適用性更廣,而非侷限在本次題目。
2. 從第一次題目到第三次題目,由於簡單的方法不再適用於下一次題目,我逐漸利用ArrayList、正規表示式等解決問題。但在實際程式碼編寫中,由於不熟悉對應的使用方法,寫出了很多錯誤程式碼,比如:利用.length獲取ArrayList的長度;在正規表示式中依靠()進行分組,但在利用.group()時常不與預期結果匹配。
3.在寫程式碼過程中,如
Test a = new Test();
Test b = a;
未注意:其中a、b指向同一片區域,修改直接修改b會將a修改的問題。應該將a的資料分別複製給b。
4.由於對各個類之間的關係及各種負責的功能考慮不周,時常出現推翻重新寫的情況,在以後應該多加思考,想清楚再動手,

4.改進建議


  • 在最後一次題目中,我設定了int陣列 delete 來儲存被刪除的題目編號,實際上,可以在question類中加入成員int states;來標識問題的狀態(0.問題正常,1.問題被刪除,2.問題回答正確 等等)。
  • 同時,在test類中,可以另設成員ArrayList questionNum;來儲存可能有的問題編號,等到全部資訊輸入完成後,再將對應的問題存入test中,即可有效解決亂序輸入的問題;

5.總結


  • 透過三次題目集練習,我逐漸理解了物件導向的程式設計好處,對類的設計有了更好的掌握。
  • 同時,還有很多實用的新東西需要學習,如HashMap、Comparable等。

建議!:老師能不能在一次題目結束後公佈所有測試點的輸入輸出啊?後面題目內容要求多,想找到自己寫的程式碼哪裡出了問題太難了,直接利用未透過的測試點資料找到錯誤可以方便很多。

相關文章