前言:
这几次关于答题判题程序是通过从键盘中输入提取出对应的信息(比如说题目,试卷,答卷等等)然后再进行逐一判断。从中考查的知识点是正则表达式的运用,加上了split函数的运用,类的数组运用等等。主要的还是这三点。由于一直的迭代,导致最终它的题目要求越来越多,导致难度直线上升。也从80行的代码最终变成了400+。所花的时间也是非常多的,在最后的迭代中我花了14小时也没有写出来,原因我也不知道为什么,莫名其妙。第一次作业,根本就没有用到类,而是直接进行了一个普通的String 的数组非常的简单暴力,但也与OOP一点也不想干,代码的质量非常的低级。然后在接下来的作业中我用上了Student Question 等各种各样的类,也渐渐有了OOP的设计思路。
设计与分析:
- 在第一次作业中,我的代码也是非常的简单。
其中运用到的就是正则表达式。当初它的判断标准是对于
题目集String regex = "#N:(\\d+) #Q:/S*(.+) #A:(.+);
看似非常的正常其实中间存在大问题好吧。因为当#Q的前面如果存在空格的话,那么就正则表达式就找不到这个情况了,然后就无法对#N那一行的信息进行拆分,这样非常有局限性。因此我的想法是运用String类函数
int m= Integer.parseInt(s.substring(s.indexOf("#N:") + 3, s.indexOf("#Q:")).trim());
String str1= s.substring(s.indexOf("#Q:") + 3, s.indexOf("#A:")).trim();
String str2= s.substring(s.indexOf("#A:") + 3).trim();
因为输入格式是固定的,所以说可以因此来找到对应的信息位置了,通过String类函数来进行切割我认为是非常的聪明的。这样就不会害怕中途是否存在空格了,如果有空格也会被我trim()给删除出去了。
答案集{String str1[]=h.split("#A:");
}由于这#A:只有对应的答案所以说我就没有考虑太多存在空格的情况,直接就是暴力切割。
当输入信息已经被我掌握了,那么就只要将他们放入数组中在最后的判断就可以了,还是非常的简单的。
2.在第二次作业中,代码就开始有一点OOP的影子了。其中涉及的类有
题目类(Answer):用于保存一道题目的信息以及处理的方法。 int n; String question; String answer;
回答类(StandardAnswer):用于保存回答题目的答案及其处理方法。int n; String standardAnswer;
试卷类(juan):用于保留一张试卷的题目和对应的分值及其处理方法。int n; int number; int grade;
由于试卷和答卷不开以判断他们的固定结构了,显然第二次作业就不可用String类函数中的substring了,应该正式开始使用正则表达式来解决问题了。其中我选择两步走,第一步就是用split函数来把将空格都给切割开{String[] parts = s.split("\\s+");
},这样的话就可以直接判断到底有多少个信息了。之后再运用一个for循环来进行正则表达式的运用。for循环的判断结构为for (int i = 1; i < parts.length; i++)
,这样就可以把该输入后面的信息给存入数组中。
3.在第三次作业中,在第二次作业上加入了一个
学生类(Studet):用于记录学生的学号及姓名。int id ; String name;
其中为了判断题目是否被删除我还在Answer类中加入了判断是否存在的存在变量
在每次判断情况下都运用了正则表达式,这也是本代码的精髓。
对于#N来说:String regex = "#N:\\s*([1-9]\\d*)\\s+#Q:(.*\\s+)#A:(.*)";
对于#T来说:则是在进行切割空格之后来将“-”前后的问题和分数进行切割处理String regexx = "(^\\d+)-(\\d+$)";
对于#S来说:也是在进行切割空格之后,将它的试卷号,学生学号,保存下来之后运用正则表达式来判断#APattern pattern4 = Pattern.compile("#A:\\s*(\\d+)\\s*-\\s*(.*?)\\s*(?=#A:|\\n|$)");
(?=#A:|\\n|$)
这个是非常的重要的,它可以判断#A后是否还有#A,以便不会出现数据没有记录的问题。
在判断输入的数据是否存在问题时,就要运用if (matcher.find())
这个,如果找到了就可以进行下一步,如果没有找到就直接输出格式错误了。与前面两次不一样的地方在于它对于试卷的题目的顺序是不一样的#S回答的答案是对于试卷的第几到题目的顺序,而试卷的题目顺序又是按照它的输入顺序,但是呢排版顺序又可以选择不一样的题目序号,当初让我困扰已久。最终我是讲试卷的题目序号用一个类数组juan1来表示,从0开始往后数,对应的就是第n位就是对应第n+1题目,之后呢又把它对应的问题号记录下来,就解决了序号没有对齐的问题。之后再进行几个for循环来解决全部问题。美中不足的是还有3个测试点没有过,但当初确实应该找不到任何问题了。
采坑心得:
(1)期间对于答案已经问题可以是文字及其它的非数字语言,因此就应该在正则表达式中使用(.*)
可以吸取包含空格的全部信息,然而一开始我一直用的就是(\\d+)
这个只是可以吸取数字,当出现中文的时候就会出现问题。
(2)每一张试卷当总分不为100分时就会出现alert: full score of test paper"+m+" is not 100 points
这种提示,并且它是出现在输出的最开始,但是当时我的代码会对应#(T/S)进行对应的输出,因此当乱序输入时就会有不足100分的情况不在输出的一开始。因此我使用一个String数组来将#S那一行的字符串存起来,当出现end之后再进行#S的判断,就可以使输出排在第一行了。
改进建议:
(1)我的代码中基本上就没有用到方法,导致main类中的代码非常杂糅,又多又乱,因此以后在编写代码的时候要多写方法,才可以让我的代码更加完美,修改起来更好,更快。
(2)在写代码的时候没有进行合理的备注,以至于到后面我都有一点不清楚写这一行是干什么的,理解起来非常的吃力。
(3)在写一些特定的类,数组时没有很好的定义名字,都是用flag1,flag2,cc等等没有特殊含义的定义变量,也会使我的代码杂乱无章。
总结:
通过这三次作业,我学习到了:
(1)正则表达式的使用方法
(2)String类的函数方法:
(3)类的定义以及使用方法
(4)private、protected、public等关键的使用场合与使用方法
同时也需要在以下方面进一步学习和研究
(1)在写代码前需要合理分析,不能走一步算一步,没有一点规划,导致到后来动不动就要修改好多东西。
(2)多运用多方法的思维进行编写程序。
(3)多加了解其他类并且能够熟练掌握它,以便在后续的学习生涯中可以将代码写的更好,时间利用率更高。
以下是我的建议:
相关建议:
希望在给出的PTA及实验的题目中尽量将问题描述的更清楚一些,以便更好的理解出题人的意思,以便写出更好的代码。