首页 > 其他分享 >PTA题目集1~3的总结

PTA题目集1~3的总结

时间:2024-04-21 22:14:39浏览次数:16  
标签:总结 输出 题目 String int 试卷 样例 PTA

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来存类。

标签:总结,输出,题目,String,int,试卷,样例,PTA
From: https://www.cnblogs.com/theBlogForStudy/p/18148110

相关文章

  • PTA前三次题目集总结
    一.前言三次PTA题目集过后,算是彻底打击了我的自信心,PTA内容不在只是简单的对语法问题的考察,真正的从“基础”转到“面向对象”,随之而来的是更多的代码量,及消耗我们更多的时间。要学习新的内容并投入实践,和更多代码量给我带来更多的报错问题和非零返回问题,无不在告诉我这次学习有......
  • OOP 1~3总结
    oop1~3总结前言知识点1.类的基本运用、类与对象的运用、类与数组的运用、关联类的使用2.接口的初步了解与运用3.日期类的使用这三次作业的最后一题涉及到的知识点比较多,综合性很强。宏观上重点考察的是我们对面向对象技术的整体把握,对程序设计原则的理解与使用,同时在细节......
  • 前三次PTA题目集总结
    1.前言:前三次作业主要都是写答题判断程序,由于这学期才接触java,所以一开始对于怎么写,以及java语法有点不太适应。后来学习到“类”这个强大的工具和正则表达式,但因为并不熟练,所以写起来十分艰难。这三次题目难度逐级提升,都在原本的基础上添加了新的内容与知识点。类和对象的使用,关......
  • opp1~3总结与反思
    23201927-杨民星-第一次博客第一次opp题集:题目数量:5题题目难度:中等偏难知识点:ArrayList变长数组,排序,正则表达式,单一职责原则等对于这次opp题集,我遇到了很多不同的情况,如下细说:第一、前几题其实都是比较简单的题目,就是让我们认......
  • RT-Thread 专栏总结
    1、对RTOS/RT-Thread优先级反转的理解参考链接1:https://blog.csdn.net/m0_74712453/article/details/134001652参考链接2:https://blog.csdn.net/weixin_45590051/article/details/118330634优先级反转是实时操作系统最常见的问题,解决办法是互斥量使用优先级继承方法。1......
  • 题目集1~3的总结
    一、前言一到三次题目集主要考察的知识点有类与对象的设计、类与方法的调用、数组、链表等;题量稍大,题目难度具有挑战性,需要经过认真的思考。二、设计与分析1、题目一:(1)题目:设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答......
  • OOP课第一阶段总结
    前三次OOP作业总结Blog前言作为第一次3+1的总结,这次题目集的难度逐渐升高,题量、阅读量和测试点的数量变化都很大,所以对我们的编程和理解能力提出了更高的要求。例如在第一次到第三次的题目集中,类的数量由三个增长到了十余个。投入的时间也由最开始的45个小时到了后来的1824......
  • PTA1-3总结w
    <1>前言:知识点:1.类的定义:代码中定义了三个类,Question、Answer和Paper,分别用来表示问题、答案和试卷。每个类都包含了相应的属性和方法。2.对象的创建:在main方法中通过new关键字创建了Question、Answer和Paper类的对象,然后对对象的属性进行赋值和操作。3.HashMap的使用:代码......
  • 关于题目集1~3的总结
    前言前三次pta作业最后一题都是答题判题程序,题目难度逐级提升但写完后收获也不小。首先一点是需求分析,不应上来就写代码而是从业务需求整体分析,在确定好程序的层次结构再开始实现相应的功能。在这三次作业中,将所学的编程知识很好地运用,其次,三次作业也同样考验我们的自学能力比......
  • NCHU题目集1~3的总结
    目录一.前言二.设计与分析三.采坑心得四.改进建议五.总结前言知识点总结题目集一字符串处理对输入的字符串进行对应的匹配与确认,找到对应的字符串的内容,将对应字符串中不合规范的内容进行处理,合格后直接存储。字符串的比对,满足要求的字符串进行输出和相应......