PTA前三次题目集总结

以下内容是我对PTA三次习题作业最后一题的思路,源码以及总结

学到的java知识大多都来自写题目集

这些题目对我对java的认知与学习起到了不小的帮助
答题判题程序-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

  • 源码展示
    import java.util.Scanner;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.*;

class Question

{

private int number=0;

private String content="";

private String standardAnswer="";

public Question()

{

}

public Question(int a,String b,String c)

{

this.number=a;

this.content=b;

this.standardAnswer=c;

}

public void setnumber(int a)

{

this.number=a;

}

public void setcontent(String a)

{

this.content=a;

}

public void setstandardAnswer(String a)

{

this.standardAnswer=a;

}

public int getnumber()

{

return number;

}

public String getcontent()

{

return content;

}

public String getstandardAnswer()

{

return standardAnswer;

}

public boolean judge(String answer)

{

return answer.equals(standardAnswer);

}

//比较答案是否相同

}

class Test

{

private List question;
private int questionnum=0;
public List getquestion()
{
return question;
}
public Test()
{
question=new ArrayList<>();
}
public Test(int a)
{
question=new ArrayList<>();
this.questionnum=a;
}
//两个构造方法
public boolean judge(int NO,String answer)
{
for(Question q:question)
{
if(q.getnumber()==NO)
{
return q.judge(answer);
}
}
return false;
}
//判断答案比较答案是否相同
public void hold(int num,String content,String answer )
{
Question q=new Question(num,content,answer);
question.add(q);
}

}

class Answer

{

private Test t=new Test();

private List an=new ArrayList<>();
private List ju=new ArrayList<>();
public List getju()
{
return ju;
}
public Test gett()
{
return t;
}
public Answer()
{
}
public void judgean(int num)
{
boolean p=t.judge(num,an.get(num-1));
ju.add(p);
}//正误卡
public void print(int num)
{
for(Question q:t.getquestion())
{
if(q.getnumber()= =num)
{
System.out.println(q.getcontent() + "~" + an.get(num-1));
}
}
}
public void savaresult(int num,String answer)
{
an.add(answer);
}//答题卡
}
public class Main
{
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
int i=input.nextInt();
input.nextLine();
String[] str=new String[i+9];
Answer ans=new Answer();
int k=0;
while(input.hasNextLine())
{
str[k++]=input.nextLine();
if(str[k-1].equals("end"))
break;
}
for(int x=0;x<i;x++)
{
String[] part=str[x].split("[#:]");
int[] record=new int[3];
int o=0;
for(int y=0;y<part.length;y++)
{
part[y]=part[y].trim();
if(part[y].equals("N"))
{
record[o++]=y+1;
}
else if(part[y].equals("Q"))
{
record[o++]=y+1;
}
else if(part[y].equals("A"))
{
record[o]=y+1;
}
}
ans.gett().hold(Integer.parseInt(part[record[0]].trim()),part[record[1]].trim(),part[record[2]].trim());
}
String[] part=str[k-2].split("[#:]");
int[] a=new int[i];
int j=0;
for(int x=0;x<part.length;x++)
{
part[x]=part[x].trim();
if(part[x].equals("A"))
{
ans.savaresult(j++,part[x+1].trim());
ans.judgean(j);
}
}
//打印出来
for(int x=0;x<i;x++)
{
ans.print(x+1);
}
for(int x=0;x<i;x++)
{
if(x==i-1)
System.out.print(ans.getju().get(x));
else
System.out.print(ans.getju().get(x)+" ");
}
}
}

  • 写题思路
    第一次的作业最后一题有设计建议,所以我是严格按照设计建议来编写代码的
    以下是设计建议
    题目类(用于封装单个题目的信息):

属性:题目编号、题目内容、标准答案-standardAnswer

方法:数据读写set\get方法、

判题方法(答案-answer):判断答案-answer是否符合标准答案-standardAnswer
试卷类(用于封装整套题目的信息)

属性:题目列表(题目类的对象集合)、题目数量

方法:判题方法(题号-num、答案-answer):判断答案-answer是否符合对应题号的题目标准答案-standardAnswer

保存题目(题号-num、题目-question):将题目保存到题目列表中,保存位置与num要能对应
答卷类(用于封装答题信息)

属性:试卷(试卷类的对象)、答案列表(保存每一题的答案)、判题列表(保存每一题的判题结果true/false)

方法:判题方法(题号-num):判断答案列表中第num题的结果是否符合试卷中对应题号的题目标准答案

输出方法(题号-num):按照题目的格式要求,输出题号为num的题目的内容和答题结果。

保存一个答案(题号-num,答案-answer):保存题号为num的题目的答题结果answer。

  • 以下是我创建的类图不包括主函数
  • 思路分析
  1. 逐行读取直到读到end结束
    2.第一行读取内容为Test里的questionnum即题目个数
    3.创建ans(Answer)
    4.读取questionnum个题目信息放入ans.t.question中,即试卷题目列表
    5.最后读取答案信息存储在ans中
    6.用ans中的答题卡来比对试卷的各个题目的standardanswer(用judge方法进行比较)并存储在正误卡中
    7.遍历正误卡输出各个题目true或者false
  • 总结

这道题目满分74,我拿了74分,比较后两次题目这道题目简单多了,还给出了设计建议,只要按照给出的设计建议来写不难写出

答题判题程序-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。

输入样例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.*;

class Question

{

private int number=0;

private String content="";

private String standardAnswer="";

public Question()

{

}

public Question(int a,String b,String c)

{

this.number=a;

this.content=b;

this.standardAnswer=c;

}

public void setnumber(int a)

{

this.number=a;

}

public void setcontent(String a)

{

this.content=a;

}

public void setstandardAnswer(String a)

{

this.standardAnswer=a;

}

public int getnumber()

{

return number;

}

public String getcontent()

{

return content;

}

public String getstandardAnswer()

{

return standardAnswer;

}

public boolean judge(String answer)

{

return answer.equals(standardAnswer);

}

//比较答案是否相同

}

class Test

{

private List question;
private List score=new ArrayList<>();
private int testnum=0;
private List number=new ArrayList<>();
public List getnumber()
{
return number;
}
public void addscore(int a)
{
score.add(a);
}
public void addquestion(Question q)
{
question.add(q);
}
public List getscore()
{
return score;
}
public List getquestion()
{
return question;
}
public Test()
{
question=new ArrayList<>();
}
public Test(int a)
{
question=new ArrayList<>();
this.testnum=a;
}
//两个构造方法
public boolean judge(int NO,String answer)
{
return question.get(NO).judge(answer);
}
//判断答案比较答案是否相同
public void settestnumber(int a)
{
this.testnum=a;
}
public int gettestnumber()
{
return testnum;
}
}
class Answer
{
private Test t;
private int answernumber=0;//bianhao
private List an=new ArrayList<>();
private List ju=new ArrayList<>();
public void setanswernumber(int a)
{
this.answernumber=a;
}
public int getanswernumber()
{
return answernumber;
}
public List getju()
{
return ju;
}
public List getan()
{
return an;
}
public void sett(Test t)
{
this.t=t;
}
public Test gett()
{
return t;
}
public Answer()
{
t=new Test();
}
public Answer(int a)
{
t=new Test();
this.answernumber=a;
}
public void addju(int num)
{
boolean p=t.judge(num,an.get(num-1));
ju.add(p);
}//正误卡
public void addan(String answer)
{
an.add(answer);
} //答题卡
public void print()
{
for(int i=0;i<t.getquestion().size();i++)
{
Question q=t.getquestion().get(i);
if(i<an.size()&&an.get(i)!=null)
{
System.out.println(q.getcontent() + "~" + an.get(i) + "~" + this.ju.get(i));
}
else
{
System.out.println("answer is null");
}
}
}
}
public class Main
{
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
List qq=new ArrayList<>();
List An=new ArrayList<>();
List Te=new ArrayList<>();
String[] str=new String[100];
int i=0;
for(;input.hasNext();i++)
{
str[i]=input.nextLine();
if(str[i].equals("end"))
break;
}
for(int k=0;k<i;k++)
{
String[] parts=str[k].split("[:#]");
int T=0,N=0,S=0;
int x=0;
for(;x<parts.length;x++)
{
if(parts[x].trim().equals("T"))
{
T=1;
break;
}
else if(parts[x].trim().equals("S"))
{
S=1;
break;
}
else if(parts[x].trim().equals("N"))
{
N=1;
break;
}
}
if(N= =1)
{
int num=0;
String con="";
String an="";
for(int y=0;y<parts.length;y++)
{
if(parts[y].trim().equals("N"))
num=Integer.parseInt(parts[y+1].trim());
else if(parts[y].trim().equals("Q"))
con=parts[y+1].trim();
else if(parts[y].trim().equals("A"))
an=parts[y+1].trim();
}
Question q=new Question(num,con,an);
qq.add(q);
}
else if(T= =1)
{
String[] part=str[k].split("[:# -]");
Test x_t=new Test();
int change=-1;
for(int y=0;y<part.length;y++)
{
if(part[y].trim().equals("T"))
{
int a=Integer.parseInt(part[y+1].trim());
x_t.settestnumber(a);
change=11;
}
else if(change= =0)
{
int c=Integer.parseInt(part[y].trim());
x_t.addscore(c);
change=1;
}//记录各个题目分数
else if(change= =1||change= =11)
{
if(change= =11)
{
change=1;
}
else if(change= =1)
{
int b=Integer.parseInt(part[y].trim());
x_t.getnumber().add(b);
/ for(Question Q:qq)
{
if(Q.getnumber()==b)
{
x_t.addquestion(Q);
break;
}
}
/
change=0;
}
}//摘录需要的题目
}
Te.add(x_t);
}
else if(S= =1)
{
String[] part=str[k].split("[:#]");
Answer a=new Answer();
for(int y=0;y<part.length;y++)
{
if(part[y].trim().equals("S"))
{
a.setanswernumber(Integer.parseInt(part[y+1].trim()));
}
else if(part[y].trim().equals("A"))
{
a.addan(part[y+1].trim());
}
}
An.add(a);
}
}
for(Test t:Te)
{
for(Integer a:t.getnumber())
{
for(Question q:qq)
{
if(a= =q.getnumber())
{
t.getquestion().add(q);
}
}
}
}
for (Answer a : An)
{
for (Test t : Te)
{
if (a.getanswernumber() == t.gettestnumber())
{
a.sett(t);
int y = 0;
while (y < a.getan().size() && a.getan().get(y) != null)
{
String x = a.getan().get(y);
if (t.getquestion().size() > y && t.getquestion().get(y) != null)
{
a.getju().add(t.judge(y, x));
}
else
{
break;
}
y++;
}
break;
}
}
}
for(Test t:Te)
{
int sum=0;
for(Integer sc:t.getscore())
{
sum=sum+sc;
}
if(sum!=100)
{
System.out.println("alert: full score of test paper" + t.gettestnumber() + " is not 100 points");
}
}
for(Answer a:An)
{
if(a.gett()!=null)
{
a.print();
}
else
continue;
List sc=new ArrayList<>();
for(int j=0;j<a.gett().getscore().size();j++)
{
if(j>=a.getju().size())
{
int x=0;
sc.add(x);
}
else if(a.getju().get(j))
{
sc.add(a.gett().getscore().get(j));
}
else
{
int x=0;
sc.add(x);
}
}
int sum=0;
for(int x=0;x<sc.size();x++)
{
System.out.print(sc.get(x));
sum=sum+sc.get(x);
if(x==sc.size()-1)
{
System.out.print("~" + sum + '\n');
}
else
{
System.out.print(" ");
}
}
}
}
}`

  • 类图

类图是手写草稿

大致内容可以看清

  • 思路分析

1.跟第一次一样依旧是那三个类question和Test和Answer

2.创建题目列表用来存储读取的题目信息,创建答题卡列表用来存储答题卡信息,创建试卷列表用来存储试卷信息

3.读取每一行直到end结束并放入一个String[]数组中

4.分析String[]数组中的每一项,先判断是题目信息还是试卷信息还是答题卡信息再对其进行相应操作(即存储信息)

5.遍历试卷列表,并从题目列表中获取该试卷需要摘录的题目信息以及对应分数

6.遍历答题卡列表,找到其对应试卷,计算该试卷的总分是否为一百进行相应的操作,并通过比对答案,输出各题的true或false以及该答卷的分数

  • 总结
    这一题的难度大大提升了,代码的长度也翻了一倍,总分73,我只拿到60分,有三个测试点没过去,没有测试实例我也真不知道bug出现在哪里,思索良久,毫无对策。
    这一题需要注意的有:添加题目进试卷是根据题目的编号加的,答题卡和正误卡没有指名题目编号,是根据题目列表中题目的索引顺序来添加的。(跟第三题的区别之一)

答题判题程序-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。

本题暂不考虑出现多张答卷的信息的情况。

  • 源码展示

`import java.util.*;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

class Question

{

private int number=0;

private String content="";

private String standardAnswer="";

public Question()

{

}

public Question(int a,String b,String c)

{

this.number=a;

this.content=b;

this.standardAnswer=c;

}

public void setnumber(int a)

{

this.number=a;

}

public void setcontent(String a)

{

this.content=a;

}

public void setstandardAnswer(String a)

{

this.standardAnswer=a;

}

public int getnumber()

{

return number;

}

public String getcontent()

{

return content;

}

public String getstandardAnswer()

{

return standardAnswer;

}

public boolean judge(String answer)

{

return answer.equals(standardAnswer);

}

//比较答案是否相同

}

class Test

{

private List question;
private List score=new ArrayList<>();
private int testnum=0;
private List number=new ArrayList<>();
public List getnumber()
{
return number;
}
public void addscore(int a)
{
score.add(a);
}
public void addquestion(Question q)
{
question.add(q);
}
public List getscore()
{
return score;
}
public List getquestion()
{
return question;
}
public Test()
{
question=new ArrayList<>();
}
public Test(int a)
{
question=new ArrayList<>();
this.testnum=a;
}
//两个构造方法
public boolean judge(int NO,String answer)
{
return question.get(NO).judge(answer);
}
//判断答案比较答案是否相同
public void settestnumber(int a)
{
this.testnum=a;
}
public int gettestnumber()
{
return testnum;
}
}
class response{
private int NO=0;
private String answer="";

public response(int number, String answer) {
    this.NO = number;
    this.answer = answer;
}

public int getNumber() {
    return NO;
}

public void setNumber(int number) {
    this.NO = number;
}

public String getAnswer() {
    return answer;
}

public void setAnswer(String answer) {
    this.answer = answer;
}

}

class Ju{

private boolean ju;

private int type;

public Ju(boolean ju, int type) {
    this.ju = ju;
    this.type = type;
}

public boolean isJu() {
    return ju;
}

public void setJu(boolean ju) {
    this.ju = ju;
}

public int getType() {
    return type;
}

public void setType(int type) {
    this.type = type;
}

}

class Answer

{

private Test t;

private String id="";

private int answernumber=0;

private List an=new ArrayList<>();
private List ju=new ArrayList<>();

public String getId() {
    return id;
}

public Test getT() {
    return t;
}

public void setT(Test t) {
    this.t = t;
}

public int getAnswernumber() {
    return answernumber;
}

public void setAnswernumber(int answernumber) {
    this.answernumber = answernumber;
}

public List<response> getAn() {
    return an;
}

public void setAn(List<response> an) {
    this.an = an;
}

public List<Ju> getJu() {
    return ju;
}

public void setJu(List<Ju> ju) {
    this.ju = ju;
}

public void setId(String id) {
    this.id = id;
}

public  void setanswernumber(int a)
{
    this.answernumber=a;
}
public  int getanswernumber()
{
    return answernumber;
}
public List<Ju> getju()
{
    return ju;
}
public  List<response> getan()
{
    return an;
}
public  void sett(Test t)
{
    this.t=t;
}
public Test gett()
{
    return t;
}
public Answer()
{
    t=new Test();
}
public Answer(int a)
{
    t=new Test();
    this.answernumber=a;
}
public void print()
{
    for(int i=0;i<ju.size();i++){//遍历正误卡,每道题都有对应的正误情况
        if(ju.get(i).getType()==0){
            String ans = null;
            for(response a:an){
                if(a.getNumber()==i+1){
                    ans=a.getAnswer();
                }
            }
            System.out.println(t.getquestion().get(i).getcontent() + "~" + ans + "~" + ju.get(i).isJu());
        }
        else if(ju.get(i).getType()==1){
            System.out.println("answer is null");
        }
        else if(ju.get(i).getType()==2){
            String ans = null;
            for(response a:an){
                if(a.getNumber()==i+1){
                    ans=a.getAnswer();
                }
            }
            System.out.println("non-existent question~" +0);
        }
        else if(ju.get(i).getType()==3){
            String ans = null;
            for(response a:an){
                if(a.getNumber()==i+1){
                    ans=a.getAnswer();
                }
            }
            System.out.println("the question " + t.getquestion().get(i).getnumber() + " invalid~" + 0);
        }
    }
}

}

class Student{

private String name="";

private String id="";

public Student(){

}
public Student(String name,String id){
    this.name=name;
    this.id=id;
}

public String getName() {
    return name;
}

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

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

}

public class Main

{

public static void main(String[] args)

{

Scanner input=new Scanner(System.in);

List qq=new ArrayList<>();
List An=new ArrayList<>();
List Te=new ArrayList<>();
List delete=new ArrayList<>();
List student=new ArrayList<>();
String[] str=new String[100];
int i=0;
for(;input.hasNext();i++)
{
str[i]=input.nextLine();
if(str[i].trim().equals("end"))
break;
}
String pattern1 = "#N:\S+ #Q:\S+ #A:\S+";
String pattern2 = "#T:\d+( \d+-\d+)+";
String pattern3 = "#X:(\S+ \S+)+(-\S+ \S+)+";
String pattern4 = "#S:\d+ \S+( #A:\d+-\S+)+";
String pattern5 = "#D:N-\d+";
String pattern6 = "#X:\S+ \S+";
Pattern[] p=new Pattern[6];
p[0]=Pattern.compile(pattern1);
p[1]=Pattern.compile(pattern2);
p[2]=Pattern.compile(pattern3);
p[3]=Pattern.compile(pattern4);
p[4]=Pattern.compile(pattern5);
p[5]=Pattern.compile(pattern6);
for(int k=0;k<i;k++){
Matcher m;
int ju=0;
for(Pattern P:p){
m=P.matcher(str[k].trim());
if(m.matches()){
ju=1;
break;
}
}
if(ju= =0){
System.out.println("wrong format:" +str[k]);
str[k]="-1";
}
}
for(int k=0;k<i;k++)
{
String[] parts=str[k].split("[:#]");
int T=0,N=0,S=0,X=0,D=0;
int x=0;
for(;x<parts.length;x++)
{
if(parts[x].trim().equals("T"))
{
T=1;
break;
}
else if(parts[x].trim().equals("S"))
{
S=1;
break;
}
else if(parts[x].trim().equals("N"))
{
N=1;
break;
}
else if(parts[x].trim().equals("X")){
X=1;
break;
}
else if(parts[x].trim().equals("D")){
D=1;
break;
}
}
if(N= =1)
{
int num=0;
String con="";
String an="";
for(int y=0;y<parts.length;y++)
{
if(parts[y].trim().equals("N"))
num=Integer.parseInt(parts[y+1].trim());
else if(parts[y].trim().equals("Q"))
con=parts[y+1].trim();
else if(parts[y].trim().equals("A"))
an=parts[y+1].trim();
}
Question q=new Question(num,con,an);
qq.add(q);
}
else if(T= =1)
{
String[] part=str[k].split("[:# -]");
Test x_t=new Test();
int change=-1;
for(int y=0;y<part.length;y++)
{
if(part[y].trim().equals("T"))
{
int a=Integer.parseInt(part[y+1].trim());
x_t.settestnumber(a);
change=11;
}
else if(change= =0)
{
int c=Integer.parseInt(part[y].trim());
x_t.addscore(c);
change=1;
}//记录各个题目分数
else if(change = =1||change= =11)
{
if(change= =11)
{
change=1;
}
else if(change= =1)
{
int b=Integer.parseInt(part[y].trim());
x_t.getnumber().add(b);
change=0;
}
}//摘录需要的题目(题号)
}
Te.add(x_t);
}
else if(S= =1)
{
String[] part=str[k].split("[: #-]");
Answer a=new Answer();
for(int y=0;y<part.length;y++){
if(part[y].trim().equals("S")){
a.setanswernumber(Integer.parseInt(part[y+1].trim()));
a.setId(part[y+2].trim());
}
if(part[y].trim().equals("A")){
response r=new response(Integer.parseInt(part[y+1].trim()),part[y+2].trim());
a.getan().add(r);
}
}
An.add(a);
}
else if(X= =1){
String[] part=str[k].split("[:# -]");
int ju=0;
int y=0;
for(;y<part.length;){
Student stu=new Student();
if(part[y].trim().equals("X")&&ju= =0){
ju=1;
y=y+1;
}
else if(ju= =1){
stu.setId(part[y].trim());
stu.setName(part[y+1].trim());
y=y+2;
student.add(stu);
}
else {
y++;
}
}
}
else if(D= =1){
String[] part=str[k].split("[:#-]");
for(int y=0;y<part.length;y++){
if(part[y].trim().equals("N")){
delete.add(Integer.parseInt(part[y+1]));
}
}
}
}
for(int y:delete){
for(Question x:qq){
if(y= =x.getnumber()){
x.setstandardAnswer("!");//删掉的题目标准答案改为!
}
}
}//处理删除了的题目
for(Test t:Te)
{
for(Integer a:t.getnumber())
{
int ju=0;
for(Question q:qq)
{
if(a= =q.getnumber())
{
t.getquestion().add(q);
ju=1;
break;
}
}
if(ju= =0){
Question q=new Question(a,"-1","#");
t.getquestion().add(q);
}
}
}//将题目加入试卷没有的就将题目标准答案改成#
for(Answer a:An){
int ju=0;
for(Test t:Te){
if(a.getanswernumber()= =t.gettestnumber()){
ju=1;
a.sett(t);
}
}
if(ju= =0){
a.setanswernumber(-1);
}
}//将有关连的答题卡和试卷连接在一起
for(Answer a:An){
if(a.getanswernumber()!=-1){
for(int x=0;x<a.gett().getquestion().size();x++){//遍历试卷上的各个问题
Question q=a.gett().getquestion().get(x);
int x1=0;
for(response r:a.getAn()){//遍历答题卡为每一道题寻找答案
if((x+1)= =r.getNumber()){
x1=1;
if(q.getstandardAnswer().equals("!")){//已经被删除的题目
Ju j=new Ju(false,3);
a.getJu().add(j);
}
else if(q.getstandardAnswer().equals("#")){
Ju j=new Ju(false,2);//题库里没有的题目
a.getJu().add(j);
}
else {
boolean ju=q.judge(r.getAnswer());
Ju j=new Ju(ju,0);
a.getJu().add(j);
}
}
}
if(x1= =0){
Ju j=new Ju(false,1);
a.getJu().add(j);
}
}
}
}
for(Test t:Te){
int sum=0;
for(Integer sc:t.getscore())
{
sum=sum+sc;
}
if(sum!=100)
{
System.out.println("alert: full score of test paper" + t.gettestnumber() + " is not 100 points");
}
}//遍历每张试卷看是不是100分满分的
for(Answer a:An){
if(a.getanswernumber()==-1){
System.out.print("The test paper number does not exist");
}
else {
a.print();
int ju=0;
for(Student stu:student){
if(a.getId().equals(stu.getId())){
ju=1;
System.out.print(stu.getId() + " " + stu.getName() + " : ");
int sum=0;
for(int x=0;x<a.getJu().size();x++){//遍历正误卡
Ju j=a.getJu().get(x);
if(j.isJu()){
System.out.print(" " +a.gett().getscore().get(x));
sum=sum+a.gett().getscore().get(x);
}
else {
System.out.print(" " + 0 );
sum=sum+0;
}
}
System.out.println("~" +sum);
}
}
if(ju= =0){//没有对应的学生
System.out.print(a.getId() + " not found");
}
}
}
}
}`

  • 类图

类图是手写草稿

能看清楚,思路更清晰

*思路分析

1.在第二次作业之上又添加了三个类,分别是student和ju和response,student用于存储学生信息,response和ju的创建是为了对答题卡和正误卡的扩展,因为第三题的答题卡上的答案和正误卡的答案不跟随试卷题目列表的索引规律,而是各个答案都有其特别的序号(此序号跟题目列表的题目索引相关)

2.在第二次的main方法基础之上需要添加student列表和delete列表分别用来存储学生的个人信息和要删除的题目的题号信息

3.需要注意的地方是(a)删除题目、(b)在题目列表中没有要摘录的题目和(c)没有答案这三种最终答案为0的情况要做上标记以便输出,我的思路是对所有要删除的题目将其standardanswer改成!,对于题目列表中没有要摘录的题目,创建一个standardanswer为#的题目并加入,并且对于相应的正误卡ju上对a,b,c问题给ju.type分别赋值3,2,1以方便区分。

4.这一题对于输入的内容有格式上的要求,需要使用到正则表达式

  • 总结

这题总分84分,我只拿了69分。目前还没有发现问题所在,比前一道题又提高了不少的难度,需要花费很长时间来理清其中的逻辑,逻辑清晰了编写代码也就得心应手了