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(){
}
}
- 第一次題目相對簡單,我透過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());
}
}
-
第二次題目存在亂序輸入,而且不再有問題總數的提示,只能判斷輸入是否為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());
}
}
-
第三次題目要求再次提升,我發現我在第二次題目中對輸入的判定在此次題目中完全不適用,於是之保留了類的基礎設計,主體全部重新再寫。
-
原始碼分析如下
-
我先利用正規表示式判斷輸入資訊是否符合標準,若符合某種輸入標準,就進入對應的操作,若不符合所以輸入標準,則為輸入格式錯誤。
-
找到對應的輸入資訊後,提取有用資訊並存入對應陣列中。
-
所有資訊輸入完畢後,先對試卷進行判定;再判定答卷,將對應的試卷資訊存入答卷中,最後對答卷進行結果判定。
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等。