1.前言
- [ 1 ] 知识点:这三次题目集是针对对象和类展开的,主要是String类和正则表达式的运用。要运用到String.split,String.substring等,和通过正则表达式来判断字符串是否符合格式和拆分字符串。
- [ 2 ] 题量:这三次题目集的题量不算很大,每次的题量有所减少,但是题目难度有所提升,每题要花的时间更多,尤其是每次题目集的最后一题。
- [ 3 ] 难度:三次题目集难度步步提升,更加考验学生对知识点的运用。第一次的题目集难度较为简单,只是一些知识点的简单运用;第二次会对输入的内容更加灵活,也增加了一些输出,要运用更多的知识进行判定;第三次是最难的,不仅增加了学生信息,还可以删除之前的信息。
2.设计与分析
- [ 1 ] 答题判题程序-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
class Question{
private int num;
private String que;
private String ans;
public int getNum(){
return num;
}
public void setNum(int num){
this.num=num;
}
public String getQue(){
return que;
}
public void setQue(String que){
this.que=que;
}
public String getAns(){
return ans;
}
public void setAns(String ans){
this.ans=ans;
}
}
class Test{
Question[] que;
void intit(int n)
{
Question[] que = new Question[n];
}
}
class Answer{
Test tes;
String[] ans;
boolean[] check;
void intit(int n)
{
ans=new String[n+1];
for(int i=0;i<=n;i++)
this.ans[i] = new String();
check = new boolean[n];
}
}
这是Question类,Test类和Answer类的设计。(由于我是将这些类放在了Main类的里面,发现有没有private都可以,就只要题目类用了private,后面的两个类就没有这么设计了,后来老师发了通知说这些类要放在Main外面才反应过来,导致我前两次PTA的作业都是因为这个扣了分,还好第三次纠正了。)Question类保存了题号,问题和答案;Test类保存了题目数组;Answer类保存了试卷,答案和对错。
通过后面两次的题目集,再看第一次设计的这三个类,尤其是Test这个类,感觉设计的不是很好。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String a= sc.nextLine();
int n=Integer.parseInt(a);
Question Que[]=new Question[n];
for (int i = 0; i < n; i++)
{
Que[i] = new Question();
String que = sc.nextLine();
String str = que.substring(que.indexOf("#N:")+3,que.indexOf("#Q:"));
str = str.strip();
Que[i].num = Integer.parseInt(str);
Que[i].que = que.substring(que.indexOf("#Q:")+3,que.indexOf("#A:"));
Que[i].que = Que[i].que.strip();
Que[i].ans = que.substring(que.indexOf("#A:")+3);
Que[i].ans = Que[i].ans.strip();
}
Arrays.sort(Que, new Comparator<Question>() {
@Override
public int compare(Question o1, Question o2) {
return o1.num-o2.num;
}
});
Test tes=new Test();
tes.intit(n);
for(int i=0;i<n;i++)
{
tes.que[i]=new Question();
tes.que[i].num=Que[i].num;
tes.que[i].que=Que[i].que;
}
Answer Ans=new Answer();
Ans.intit(n);
String ans=sc.nextLine();
Ans.ans=ans.split("#A:");
for(int i=0;i<n;i++) {
Ans.ans[i] = Ans.ans[i+1].strip();
if (Que[i].ans.compareTo(Ans.ans[i]) == 0)
Ans.check[i] = true;
}
for(int i=0;i<n;i++)
{
System.out.println(Que[i].que+"~"+Ans.ans[i]);
}
for(int i=0;i<n;i++)
{
System.out.printf("%b",Ans.check[i]);
if(i<n-1)
System.out.printf(" ");
}
}
这部分是主函数的设计,这题(7-5)不是很难。通过下面的图片就可以看到,这题我是提交了一次就过了的,这题还是比基础的了。
- [ 2 ] 答题判题程序-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
class Question{
private int num;
private String que;
private String ans;
public int getNum(){
return num;
}
private int point;
public void setNum(int num){
this.num=num;
}
public String getQue(){
return que;
}
public void setQue(String que){
this.que=que;
}
public String getAns(){
return ans;
}
public void setAns(String ans){
this.ans=ans;
}
public int getPoint(){
return point;
}
public void setPoint(int point){
this.point=point;
}
}
class Test{
int num=0;
Question[] que;
int sum=0;
void intit()
{
que = new Question[0];
}
}
class Answer{
int num;
Test tes;
String[] ans;
int[] point;
int sum=0;
boolean exist;
boolean[] check;
void intit(int n)
{
ans = new String[n];
for(int i=0;i<n;i++)
ans[i]=new String();
point=new int[n];
check = new boolean[n];
}
}
题目的要求更多了,所以类的内容也加了一些。每个题目有了分数;还会有多张试卷,所以试卷也增加了试卷号;在答卷中不仅会判断对错,如果对了,还会加上相应的分数,答卷也会引用试卷号,以及试卷是否存在。但是写完感觉这个分数应该单独放一个类会更好。因为这个分数是在输入Test类的时候才会有的,当时应为在Test类里放了Question类数组了,感觉这个分数就直接在Question类,虽然不影响结果,但是单独设计一个Point类在思路上会更清晰一些,当其他人读这个代码的时候应该会更加容易读懂。
if (a.charAt(1) == 'N') {
Question[] q = new Question[Que.length + 1];
int sum = 0;
for (i = 0; i < Que.length; i++) {
q[i] = Que[i];
}
q[i] = new Question();
String str = a.substring(a.indexOf("#N:") + 3, a.indexOf("#Q:"));
str = str.strip();
q[i].num = Integer.parseInt(str);
q[i].que = a.substring(a.indexOf("#Q:") + 3, a.indexOf("#A:"));
q[i].que = q[i].que.strip();
q[i].ans = a.substring(a.indexOf("#A:") + 3);
q[i].ans = q[i].ans.strip();
Que = q;
Arrays.sort(Que, new Comparator<Question>() {
@Override
public int compare(Question o1, Question o2) {
return o1.num - o2.num;
}
});
}
这是将题目信息保存到Question里,#N:和#Q:里的为题号,#Q:和#A:里的为题目,#A:后面的为答案,每个都会去掉开头和末尾的空格。后面的重写sout现在感觉没什么必要,这题本来就是乱序输入,还可能会少题,排序就感觉多余了,而且后面输出的时候还是会通过题号来找到相应的题目的。
if (a.charAt(1) == 'T') {
Test[] t = new Test[Tes.length + 1];
for (i = 0; i < Tes.length; i++) {
t[i] = Tes[i];
}
t[i] = new Test();
t[i].intit();
String str = a.substring(a.indexOf("#T:") + 3, a.indexOf("-") - 1);
str = str.strip();
t[i].num = Integer.parseInt(str);
a = a.substring(a.indexOf("-") - 1);
String[] QP = a.split("\\s+");
for (int x = 0; x < QP.length; x++) {
String[] Q_P = QP[x].split("-");
Question[] q = new Question[t[i].que.length + 1];
int j;
for (j = 0; j < t[i].que.length; j++)
q[j] = t[i].que[j];
q[j] = new Question();
q[j].num = Integer.parseInt(Q_P[0]);
q[j].point = Integer.parseInt((Q_P[1]));
t[i].sum += q[j].point;
t[i].que = q;
}
Tes = t;
}
这是将试卷信息保存到Test里,先将#T:后面的数字存起来,为试卷号,后面没一部分按空格分割成字符串数组,每个字符串按"-"分开,前面的是题号,后面的是分数。
if (a.charAt(1) == 'S') {
Answer[] an = new Answer[Ans.length + 1];
for (i = 0; i < Ans.length; i++) {
an[i] = Ans[i];
}
an[i] = new Answer();
String res = a.substring(a.indexOf("#S:")+4);
res=res.strip();
if(res.compareTo("")==0)
{
String str = a.substring(a.indexOf("#S:") + 3);
str = str.strip();
an[i].num = Integer.parseInt(str);
for (int x = 0; x < Tes.length; x++) {
if (Tes[x].num == an[i].num) {
an[i].intit(Tes[x].que.length);
an[i].exist=true;
break;
}
}
an[i].ans=null;
}
else
{
String str = a.substring(a.indexOf("#S:") + 3, a.indexOf("#A:"));
str = str.strip();
an[i].num = Integer.parseInt(str);
for (int x = 0; x < Tes.length; x++) {
if (Tes[x].num == an[i].num) {
an[i].intit(Tes[x].que.length);
an[i].exist=true;
break;
}
}
a = a.substring(a.indexOf("#A:"));
an[i].ans=a.split("#A:");
for (int j = 0; j < an[i].ans.length-1; j++) {
an[i].ans[j] = an[i].ans[j + 1].strip();
}
}
Ans=an;
}
这段是将答卷的信息保存到Answer里,if(res.compareTo("")==0)是当输入的答案个数为0个的时候,else后面是正常的输入,先将#S:和#A:中间的数字提取出来,为题试卷号。再将#A:的字符串按#A:分割开每一部分为答卷的答案。
for (int i = 0; i < Tes.length; i++) {
if (Tes[i].sum != 100)
System.out.println("alert: full score of test paper" + (Tes[i].num) + " is not 100 points");
}
这是当总分不是100分的时候要输出的结果。在这个地方我也是处处碰壁了。
我最开始的是这样的
for (int i = 0; i < Tes.length; i++) {
if (Tes[i].sum < 100)
System.out.println("alert: full score of test paper" + (i + 1) + " is not 100 points");
}
那时直接忽略了试卷号了,直接输出的是第几次输入的试卷了,也是造成了很多的错误
后面代码改成下面这样的
for (int i = 0; i < Tes.length; i++) {
if (Tes[i].sum < 100)
System.out.println("alert: full score of test paper" + (Tes[i].num) + " is not 100 points");
}
当时真是没看清题目,就是一个"!="和"<"的区别,导致我浪费了很多时间,看看下面的图片,这段时间一直是在找这个错误,要不是我问了同学根本找不到了。
for(int i=0;i<Ans.length;i++)
{
if(Ans[i].ans!=null)
{
for(int x=0;x<Tes.length;x++)
{
if(Tes[x].num==Ans[i].num)
{
for (int j = 0; j < Ans[i].ans.length-1; j++) {
for(int z=0;z<Que.length;z++)
{
if(Que[z].num==Tes[x].que[j].num)
{
if(Que[z].ans.compareTo(Ans[i].ans[j])==0)
{
Ans[i].point[j]+=Tes[x].que[j].point;
Ans[i].check[j]=true;
Ans[i].sum+=Tes[x].que[j].point;
}
}
}
}
}
}
}
}
这段是判断答卷每题对错以及给每题加分
for(int i=0;i<Ans.length;i++) {
if(!Ans[i].exist)
{
System.out.println("The test paper number does not exist");
}
else
{
if(Ans[i].ans==null)
{
for (int x = 0; x < Tes.length; x++)
{
if (Tes[x].num == Ans[i].num) {
System.out.println("answer is null");
for (int j = 0; j < Tes[x].que.length; j++) {
System.out.printf("%d", Ans[i].point[j]);
if (j < Tes[x].que.length - 1)
System.out.printf(" ");
else
System.out.printf("~");
}
System.out.printf("%d\n", Ans[i].sum);
break;
}
}
continue;
}
for (int x = 0; x < Tes.length; x++) {
if (Tes[x].num == Ans[i].num) {
for (int j = 0; j < Ans[i].ans.length - 1; j++) {
for(int y=0;y<Que.length;y++)
{
if(Que[y].num==Tes[x].que[j].num)
{
System.out.println(Que[y].que + "~" + Ans[i].ans[j] + "~" + Ans[i].check[j]);
break;
}
}
}
for(int h=0;h<Tes[x].que.length-(Ans[i].ans.length - 1);h++)
System.out.println("answer is null");
for (int j = 0; j < Tes[x].que.length; j++) {
System.out.printf("%d", Ans[i].point[j]);
if (j < Tes[x].que.length - 1)
System.out.printf(" ");
else
System.out.printf("~");
}
System.out.printf("%d\n", Ans[i].sum);
break;
}
}
}
}
这是最后输出结果。当答案答案一个都没有的时候每个题目都会输出"answer is null",也就是当试卷有这题,但是答卷没有都是这么输出的,要是有这题,就输出这题的题目,答卷上的答案和答案的对错。另外还要输出每题的得分和总分。
其中
if(!Ans[i].exist)
{
System.out.println("The test paper number does not exist");
}
这一段在最开始写的时候忘记了,最后一个样例还错了,当时没测这个,忘记了还有这个情况,不过还是及时发现了。
- [ 3 ] 答题判题程序-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
class Question{
private int num;
private String que;
private String ans;
private int point;
boolean exist;
public int getNum(){
return num;
}
public void setNum(int num){
this.num=num;
}
public String getQue(){
return que;
}
public void setQue(String que){
this.que=que;
}
public String getAns(){
return ans;
}
public void setAns(String ans){
this.ans=ans;
}
public int getPoint(){
return point;
}
public void setPoint(int point){
this.point=point;
}
public boolean getExist(){
return exist;
}
public void setExist(boolean exist){
this.exist=exist;
}
}
class Test{
private int num=0;
Question[] que= new Question[0];
private int sum=0;
public int getNum(){
return num;
}
public void setNum(int num){
this.num=num;
}
public int getSum(){
return sum;
}
public void setSum(int sum){
this.sum=sum;
}
}
class Answer{
private int num;
private String sid;
Test tes;
private String[] ans;
private int[] point=new int[0];
private int[] anu=new int[0];
private int sum=0;
private boolean exist;
private boolean[] check=new boolean[0];
void intit(int n)
{
this.anu = new int[n];
this.point = new int[n];
this.check = new boolean[n];
}
public int getNum(){
return num;
}
public void setNum(int num){
this.num=num;
}
public String getSid(){
return sid;
}
public void setSid(String sid){
this.sid=sid;
}
public String[] getAns(){
return ans;
}
public void setAns(String[] ans){
this.ans=ans;
}
public int[] getPoint() {
return point;
}
public void setPoint(int[] point) {
this.point = point;
}
public int[] getAnu() {
return anu;
}
public void setAnu(int[] anu) {
this.anu = anu;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
public boolean getExist(){
return exist;
}
public void setExist(boolean exist) {
this.exist = exist;
}
public boolean[] getCheck() {
return check;
}
public void setCheck(boolean[] check) {
this.check = check;
}
}
class Student{
private String sid;
private String name;
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;
}
}
class Delet{
private int[] num=new int[0];
public int[] getNum() {
return num;
}
public void setNum(int[] num) {
this.num = num;
}
}
这是本题类的设计,这次是根据老师的提示把类建到了Main外面了。这次多加了一个Student类,来保存学生信息;多加了一个Delet类,保存删除的题目。Question类多加了一个判断题目是否存在;Test类里本来有一个intit方法,后面发现没用就删了;Answer类也加了答题的学生学号,还有每个答案有对应的题目序号,序号对应的是在Test里的第几题(这个我本来以为是对应的Question类的题号,所以会有错误,当时还是问了同学才发现的);Answer类里的intit方法也是没用的,我是后面改了主函数,就没用到这个了,这里忘记删掉了。
if(a.matches("#N:\\s*\\d+\\s*#Q:.*#A:.*"))
if(a.matches("#T:\\s*(\\d+)\\s*(\\d+-\\d+\\s*)*"))
if (a.matches("#S:\\s*(\\d+)\\s+(\\w*)\\s*(#A:\\s*(\\d+-?[^#]*))*"))
if(a.matches("#X:\\s*(\\w+)\\s*(.*)(-(\\w+)\\s*(.*))*"))
if(a.matches("#D:\\s*N-\\s*\\d+\\s*"))
这是通过正则表达式来判断字符串是否符合格式。
if (a.startsWith("#N:")) {
if(a.matches("#N:\\s*\\d+\\s*#Q:.*#A:.*")){
Question[] q = new Question[Que.length + 1];
int sum = 0;
for (i = 0; i < Que.length; i++) {
q[i] = Que[i];
}
q[i] = new Question();
String str = a.substring(a.indexOf("#N:") + 3, a.indexOf("#Q:"));
str = str.strip();
q[i].setNum(Integer.parseInt(str));
q[i].setQue(a.substring(a.indexOf("#Q:") + 3, a.indexOf("#A:")));
q[i].setQue(q[i].getQue().strip());
q[i].setAns(a.substring(a.indexOf("#A:") + 3));
q[i].setAns(q[i].getAns().strip());
q[i].setExist(true);
Que = q;
}
else
System.out.println("wrong format:"+a);
}
这是将题目信息保存到Question里,#N:和#Q:里的为题号,#Q:和#A:里的为题目,#A:后面的为答案,每个都会去掉开头和末尾的空格。
else if (a.startsWith("#T:")) {
if(a.matches("#T:\\s*(\\d+)\\s*(\\d+-\\d+\\s*)*")){
Test[] t = new Test[Tes.length + 1];
for (i = 0; i < Tes.length; i++) {
t[i] = Tes[i];
}
t[i] = new Test();
String[] str1 = a.split(" ");
str1[0] = str1[0].substring(str1[0].indexOf("#T:") + 3);
if (str1.length == 1) {
t[i].setNum(Integer.parseInt(str1[0].strip()));
Tes = t;
a = sc.nextLine();
continue;
}
String regex = "#T:\\s*(\\d+)\\s*(.*)";
Pattern pat = Pattern.compile(regex);
Matcher mat = pat.matcher(a);
mat.find();
int pid = Integer.parseInt(mat.group(1).trim());
t[i].setNum(pid);
Pattern pat1 = Pattern.compile("(\\d+)-(\\d+)");
Matcher mat1 = pat1.matcher(a);
while(mat1.find())
{
int qid=Integer.parseInt(mat1.group(1));
int score =Integer.parseInt(mat1.group(2));
Question[] q = new Question[t[i].que.length + 1];
int j;
for (j = 0; j < t[i].que.length; j++)
q[j] = t[i].que[j];
q[j] = new Question();
q[j].setNum(qid);
q[j].setPoint(score);
t[i].setSum(t[i].getSum()+ q[j].getPoint());
t[i].que = q;
}
Tes = t;
}
else
System.out.println("wrong format:"+a);
}
这是将试卷信息保存到Test里,将字符串按空格分割,如果分割的结果为1 ,则试卷没有题目,但是后面发现不会有这种情况。后面是通过正则表达式把每个题号和分数切割下来,分别存到对应的数据里。这里和之前有些差别,这是通过正则表达式来切割字符串的,之前是用String.substring切割的,对比之下还是正则表达式好一点,我这是同学教我的,因为我一直在找一个错误,所以这部分换成了正则表达式来切割了。
以下是我自己写的
else if (a.startsWith("#T:")) {
if(!a.matches("#T:\\s*(\\d+)\\s*(\\d+-\\d+\\s*)*"))
System.out.println("wrong format:"+a);
else{
Test[] t = new Test[Tes.length + 1];
for (i = 0; i < Tes.length; i++) {
t[i] = Tes[i];
}
t[i] = new Test();
String[] str1 = a.split(" ");
str1[0] = str1[0].substring(str1[0].indexOf("#T:") + 3);
if (str1.length == 1) {
t[i].setNum(Integer.parseInt(str1[0].strip()));
Tes = t;
a = sc.nextLine();
continue;
}
String str = a.substring(a.indexOf("#T:") + 3, a.indexOf(" "));
str = str.strip();
t[i].setNum(Integer.parseInt(str));
a = a.substring(a.indexOf("-") - 1);
String[] QP = a.split("\\s+");
for (int x = 0; x < QP.length; x++) {
String[] Q_P = QP[x].split("-");
Question[] q = new Question[t[i].que.length + 1];
int j;
for (j = 0; j < t[i].que.length; j++)
q[j] = t[i].que[j];
q[j] = new Question();
q[j].setNum(Integer.parseInt(Q_P[0]));
q[j].setPoint(Integer.parseInt((Q_P[1])));
t[i].setSum(t[i].getSum()+ q[j].getPoint());
t[i].que = q;
}
Tes = t;
}
}
主要还是应为当题目数字不是个位数我的切割就会出现问题。
else if (a.startsWith("#S:")) {
if (a.matches("#S:\\s*(\\d+)\\s+(\\w*)\\s*(#A:\\s*(\\d+-?[^#]*))*")){
Answer[] an = new Answer[Ans.length + 1];
for (i = 0; i < Ans.length; i++) {
an[i] = Ans[i];
}
an[i] = new Answer();
String[] str = a.split("\\s+");
str[0] = str[0].substring(str[0].indexOf("#S:") + 3);
an[i].setNum(Integer.parseInt(str[0]));
an[i].setSid(str[1].strip());
if (str.length == 2) {
an[i].setAns(null);
Ans=an;
break;
}
String a1=a.substring(a.indexOf("#A:"));
str=a1.split("#A:");
an[i].setAns(new String[0]);
an[i].setCheck(new boolean[0]);
an[i].setAnu(new int[0]);
an[i].setPoint(new int[0]);
for (int j = 0; j < str.length-1; j++) {
String[] res = str[j+1].split("-");
String[] ann=new String[an[i].getAns().length+1];
int[] anu = new int[an[i].getAnu().length+1];
int[] point = new int[an[i].getPoint().length+1];
boolean[] check = new boolean[an[i].getCheck().length+1];
int z;
for(z=0; z< an[i].getAns().length; z++)
{
anu[z]= an[i].getAnu()[z];
ann[z]= an[i].getAns()[z];
}
anu[z] = Integer.parseInt(res[0].strip());
ann[z] = new String();
ann[z] = res[1].strip();
an[i].setAnu(anu);
an[i].setAns(ann);
an[i].setPoint(point);
an[i].setCheck(check);
}
Ans = an;
}
else
System.out.println("wrong format:" + a);
}
这是将答卷信息保存到Answer里,先将字符串通过空格分割,读取分割后第一个字符串#S:后面的数字即试卷号,第二个字符串为学号,如果只有两个字符串那么答案内容为空,否则就把每个答案按照"-"分割,第一个是题目序号,第二个是答案。
else if (a.startsWith("#X:"))
{
if(a.matches("#X:\\s*(\\w+)\\s*(.*)(-(\\w+)\\s*(.*))*")){
a=a.substring(a.indexOf("#X:")+3);
if(a.contains("-"))
{
String[] str=a.split("-");
Student[] s = new Student[Stu.length+str.length];
for (i = 0; i < Stu.length; i++) {
s[i] = Stu[i];
}
for(int j=0;j<str.length;j++)
{
str[j].strip();
String[] res=str[j].split("\\s+");
if(res[0].compareTo("")==0) {
s[i+j] = new Student();
s[i + j].setSid(res[1]);
s[i + j].setName(res[2]);
}
else {
s[i+j] = new Student();
s[i + j].setSid(res[0]);
s[i + j].setName(res[1]);
}
}
Stu=s;
}
else {
Student[] s = new Student[Stu.length+1];
for (i = 0; i < Stu.length; i++) {
s[i] = Stu[i];
}
String[] res=a.split("\\s+");
if(res[0].compareTo("")==0) {
s[i] = new Student();
s[i].setSid(res[1]);
s[i].setName(res[2]);
}
else {
s[i] = new Student();
s[i].setSid(res[0]);
s[i].setName(res[1]);
}
Stu=s;
}
}
else
System.out.println("wrong format:"+a);
}
这里是将学生信息保存到Student里,这段感觉我写的比较复杂了,不知道用正则表达式来切割字符串的话是不是就不会这么复杂了。我得判断字符串里是否含有"-"来判断是否不止一个学生,如果多个学生就要在通过"-"来切割每一段学生信息,每一段学生信息里通过空格来切割学号和名字。
if(a.matches("#D:\\s*N-\\s*\\d+\\s*")) {
a=a.substring(a.indexOf("-")+1);
a=a.strip();
int t=Integer.parseInt(a);
for(i=0;i<Que.length;i++)
if(Que[i].getNum() ==t)
Que[i].setExist(false);
}
else
System.out.println("wrong format:"+a);
这段是将删除内容读取,再找到删除的题目。这里没用到Delet了,我本来创Delet的类是怕删除的题目在题目出现之前,后面案例说明不会有这种情况,所以就没用了。
for(int i=0;i<Ans.length;i++)
{
for(int x=0;x<Tes.length;x++)
{
if(Ans[i].getNum() == Tes[x].getNum())
Ans[i].setExist(true);
}
}
这里是判断答卷里的试卷号是否存在。
for (int i = 0; i < Tes.length; i++) {
if (Tes[i].getSum() != 100)
System.out.println("alert: full score of test paper" + (Tes[i].getNum()) + " is not 100 points");
}
这是输出试卷分数不为100分的
for(int i=0;i<Ans.length;i++)
{
if(Ans[i].getAns() !=null)
{
for(int x=0;x<Tes.length;x++)
{
if(Tes[x].getNum() == Ans[i].getNum())
{
for(int j = 0; j< Ans[i].getAns().length; j++)
{
if(Ans[i].getAnu()[j]-1<Tes[x].que.length){
for(int z=0;z<Que.length;z++)
{
if(Que[z].getNum() == Tes[x].que[Ans[i].getAnu()[j] - 1].getNum())
{
if(Que[z].getAns().compareTo(Ans[i].getAns()[j])==0&&Que[z].exist)
{
Ans[i].getPoint()[j]+= Tes[x].que[Ans[i].getAnu()[j] - 1].getPoint();
Ans[i].getCheck()[j]=true;
Ans[i].setSum(Ans[i].getSum()+ Tes[x].que[Ans[i].getAnu()[j] - 1].getPoint());
}
}
}
}
}
}
}
}
}
这是判断答卷的内容的正误,并赋分。
for(int i=0;i<Ans.length;i++) {
if(!Ans[i].getExist())
{
System.out.println("The test paper number does not exist");
}
else
{
if(Ans[i].getAns() ==null)
{
for (int x = 0; x < Tes.length; x++)
{
if (Tes[x].getNum() == Ans[i].getNum()) {
for (int j = 0; j < Tes[x].que.length; j++)
{
System.out.println("answer is null");
}
boolean cout=false;
for(int j=0;j<Stu.length;j++)
{
if(Stu[j].getSid().compareTo(Ans[i].getSid())==0) {
System.out.printf("%s %s: ", Stu[j].getSid(), Stu[j].getName());
break;
}
else if(j==Stu.length-1) {
System.out.println(Ans[i].getSid() + " not found");
cout=true;
}
}
if(cout)
break;
for (int j = 0; j < Tes[x].que.length; j++) {
System.out.printf("0");
if (j < Tes[x].que.length - 1)
System.out.printf(" ");
else
System.out.printf("~");
}
System.out.printf("0");
break;
}
}
continue;
}
for (int x = 0; x < Tes.length; x++) {
if (Tes[x].getNum() == Ans[i].getNum()) {
for (int y = 0; y < Tes[x].que.length; y++) {
for(int j = 0; j< Ans[i].getAns().length; j++)
{
if(Ans[i].getAnu()[j]==(y+1))
{
for(int z=0;z<Que.length;z++)
{
if(Que[z].getNum() == Tes[x].que[y].getNum())
{
if(Que[z].exist)
{
System.out.println(Que[z].getQue() + "~" + Ans[i].getAns()[j] + "~" + Ans[i].getCheck()[j]);
break;
}
else {
System.out.println("the question " + Tes[x].que[y].getNum() + " invalid~0");
break;
}
}
else if(z==Que.length-1)
System.out.println("non-existent question~0");
}
if(Que.length==0)
{
System.out.println("non-existent question~0");
}
break;
}
else if(j== Ans[i].getAns().length-1)
System.out.println("answer is null");
}
}
boolean cout=false;
for(int j=0;j<Stu.length;j++)
{
if(Stu[j].getSid().compareTo(Ans[i].getSid())==0) {
System.out.printf("%s %s: ", Stu[j].getSid(), Stu[j].getName());
break;
}
else if(j==Stu.length-1) {
System.out.println(Ans[i].getSid() + " not found");
cout=true;
}
}
if(cout)
break;
for (int y = 0; y < Tes[x].que.length; y++) {
for(int j = 0; j< Ans[i].getAns().length; j++) {
if (Ans[i].getAnu()[j] == (y+1)) {
System.out.printf("%d", Ans[i].getPoint()[j]);
if (y < Tes[x].que.length - 1)
System.out.printf(" ");
else
System.out.printf("~");
break;
}
else if(j== Ans[i].getAns().length-1)
{
System.out.printf("0");
if (y < Tes[x].que.length - 1)
System.out.printf(" ");
else
System.out.printf("~");
}
}
}
System.out.printf("%d\n", Ans[i].getSum());
break;
}
}
}
}
这是最后的输出结果,如果答卷没有匹配的试卷号,则输出"The test paper number does not exist",否则正常输出。再判断答卷的内容是否为空,如果是空,就每个题目就输出"answer is null",再输出学生的学号姓名,如果找不到学生就输出学号not found,找到就输出各个题目得分情况,并输出总分;如果答案不是空,通过试卷题目找答卷里是否回答了这题,如果没回答就输出"answer is null",如果回答了,就找这个题目是不是题库里有的,没有就输出:"non-existent question~0",有的就看这题有没有被删除,如果被删了,就输出:"the question " + Tes[x].que[y].getNum() + " invalid~0",没被删就输出题目和答卷答案以及对错。再输出学生的学号姓名,如果找不到学生就输出学号not found,找到就输出各个题目得分情况,并输出总分。
这样这个答题判断程序就完成了。
3. 踩坑心得
再设计与分析的过程中就已经讲过部分我踩过的坑了,这里再最后总结一下:一定要看清楚题目的要求,在第二次题目集中的输出试卷不是100的时候,我要么就是没输出对应的试卷号,要么就是没注意是"<"还是"!=",还有第三次题目集里在分割字符串的时候,Test里的题目分割我写的只适用个位数题目。另外还有一个最大的坑,就是当一个题目都没有的情况,试卷引用了错误题目,我是没有输出的,这个错误的好像我身边的同学都没有踩到,导致我在找这个错误的时候找了两天都没找到,甚至到最后题目集结束了我都没找到。
从这几张图就可以看到我当时内心有多么痛苦了一直在找这个错误,虽然有在最后一天有分加了,这还是我在找这个错误的时候找到的。
if(Que.length==0)
{
System.out.println("non-existent question~0");
}
这个主要还是逻辑错误,就加了这个就过了。
4.改进建议
- [ 1 ] 我是用类数组将数据存入类中,也可以用Hashmap来存。尤其是像我上面提到的最后一个坑,要是用Hashmap就不会遇到这样的情况了,直接用map里的是否为空来判断就行了。
- [ 2 ] 切割字符串的时候还是通过用正则表达式来切割更加方便,不然用String.substring和split切割会另外增加很对判断,将题目复杂化了。
5.总结
通过这三次题目集,我加深了对类和对象的理解,也更熟悉了用String.substring和split来切割字符串,以及对正则表达式的运用。不过还需要多学习Hashmap的使用,尝试把这次的代码换成Hashmap来存类。