一、作业总结
从难度来看,这三次的大作业最后一题都是由一种题目发展扩充来的,不断的深入。因为每次的最后一题涉及的范围越来越广、对每条输入的格式严格要求以及在不同情况下输出不同的语句,所以显而易见的,三次作业的难度在逐渐提升,这也就代表着我们需要更好的思维和逻辑以及方法。
从知识点的涉及来看,这三次的题目所要运用的知识点越来越多,它涉及到了对正则表达式的运用(这对输入格式的判断有着很大的帮助,减少了我的代码量以及降低了分隔字符的难度,很轻松的判断格式以及获取输入中的所需信息)、ArrayList和哈希表(这能够很好的帮我添加内容、查找内容以及删除内容)。而最重要的是对类的建立,分析好每次所需的对象,判断类中所要用的方法以及类与类之间的关系和联系。
从每次作业的题量来说,每次大作业的题量都还好,并且每次大作业前面的几个小题都能提前训练最后一题所要用或理解的东西,这对我就有了一个过渡作用,不至于一点头绪都没有。
而从每次的结果来看,让我不甚满意。对于第一次的作业还是很轻松的,基本上是不需要什么的(有了C语言上的基础倒也能完成)。但是从第二次的作业来看,就开始有点力不从心了。由于没有很好的规划类,我的代码就很杂,一次又一次的循环和if嵌套,之间的关系开始变得混杂,有点理不清理,测试点都是一点一点的过。自然而然,到了最后一次作业,更是寸步难行,格式中的种种要求应接不暇,常常顾此失彼。这也让我认识到了设计类的重要。
接下来我将要对每次的作业进行分析。
二、作业分析
1.答题判断程序-1(第一次作业)
因为这次的作业还是很简单的,几乎没有面向对象的影子,所以只是建了一个Question类(问题类)和一个Answer类(答案类)以及一个主类。先用正则表达式分别提取输入的问题和答案,然后分别存入Question数组以及Answer数组中,最后一一匹配答案的正确性输出结果。
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question{
private int num;
private String title,standardAnswer;
Question(int num,String title,String standardAnswer){
this.num=num;
this.title=title;
this.standardAnswer=standardAnswer;
}
int getnum()
{return num;}
String gettitle()
{return title;}
String getstandardAnswer()
{return standardAnswer;}
public void setnum(int num)
{num= num;}
public void settitle(String title)
{title= title;}
public void setstandardAnswer(String standardAnswer)
{standardAnswer=standardAnswer;}
}
class Answer{
private String answer;
Answer(String answer){
this.answer=answer;
}
String getanswer()
{return answer;}
}
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int i,j;
int count = Integer.parseInt(sc.nextLine());
Question[] ques=new Question[count];
String regex="#N:\\s*(\\d+)\\s+#Q:\\s*(.*?)\\s+#A:\\s*(.*)";
for (i = 0; i < count; i++) {
String str = sc.nextLine();
Pattern p=Pattern.compile(regex);
Matcher matcher =p.matcher(str);
if (matcher.find()) {
int num = Integer.parseInt(matcher.group(1));
String title = matcher.group(2);
String standardAnswer = matcher.group(3);
ques[i] = new Question(num, title, standardAnswer);
}
}
for(i=0;i<count-1;i++){
for(j=0;j<count-i-1;j++){
if(ques[j].getnum()>ques[j+1].getnum()){
Question t = ques[j];
ques[j]=ques[j+1];
ques[j+1]=t;
}
}
}
String str1;
Answer[] an=new Answer[count];
String regex1="#A:(.+)$";
i=0;
while (!(str1= sc.next()).equals("end")){
Pattern p1=Pattern.compile(regex1);
Matcher matcher1 =p1.matcher(str1);
while (matcher1.find()) {
String answer1 = matcher1.group(1);
an[i] = new Answer(answer1);
i++;
}
}
for(i=0;i<count;i++){
System.out.println(ques[i].gettitle()+"~"+an[i].getanswer());
}
for(i=0;i<count;i++){
boolean s=(ques[i].getstandardAnswer()).equals(an[i].getanswer());
if(i==0)
System.out.printf("%s",s);
else
System.out.printf(" %s",s);
}
}
}
这次作业的最大问题就是正则表达式的表达,运用了工具Patter和Matcher。一开始不知道group与括号之间的联系,所以总是出现问题。
group(n)括号中的数字匹配的是表达式中所符合的第n个括号中的内容。从前,只知道正则表达式的强大和方便,现在,我也知道了它不是那么容易写出来的,它的每个符号都有他的用处。
2.答案判断程序-2(第二次作业)
这一题比上一题难了不止一点,因为它在上一次作业的基础上加了很多的条件,并且它需要增加试卷类,题目在一点一点的深入。这次因为它出现了多张试卷和多份答卷。所以还不会用哈希表和ArrayList的我采用了类的二维数组,但这时的复杂度就很高了,有很多的if语句和for语句,不断的去过测试点以获取每一测试点的分,这也就使得嵌套混杂在一起,最后结果可想而知并没有全部通过。
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question{
private int num;
private String title,standardAnswer;
Question(int num,String title,String standardAnswer){
this.num=num;
this.title=title;
this.standardAnswer=standardAnswer;
}
int getnum()
{return num;}
String gettitle()
{return title;}
String getstandardAnswer()
{return standardAnswer;}
public void setnum(int num)
{num= num;}
public void settitle(String title)
{title= title;}
public void setstandardAnswer(String standardAnswer)
{standardAnswer=standardAnswer;}
}
class Test{
private int num,count,score;
Test(int count,int score){
this.count=count;
this.score=score;
}
int getCount(){
return count;
}
int getScore(){
return score;
}
}
class Answer{
private String answer;
Answer(String answer){
this.answer=answer;
}
String getanswer()
{return answer;}
}
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int i=0,j=0,k=0,sum1=0,sum2=0,sum3=0,x,y;
String str=null;
Question[] ques=new Question[100];
Test[][] test=new Test[100][100];
Answer[][] an=new Answer[100][100];
int[] arr1 = new int[100];
int[] arr2 = new int[100];
int[] a1=new int[100];
int[] a2=new int[100];
for(i=0;i<100000;i++)
{
str= sc.nextLine();
if(str.equals("end")) {
break;
}
boolean b1=str.matches("#N:(.+)$");
boolean b2=str.matches("#T:(.+)$");
boolean b3=str.matches("#S:(.+)$");
if(b1==true) {
String regex="#N:\\s*(\\d+)\\s+#Q:\\s*(.*?)\\s+#A:\\s*(.*)";
Pattern p=Pattern.compile(regex);
Matcher matcher =p.matcher(str);
if (matcher.find()) {
int num = Integer.parseInt(matcher.group(1));
String title = matcher.group(2);
String standardAnswer = matcher.group(3);
ques[sum1] = new Question(num, title, standardAnswer);
}
sum1++;
}
else if(b2==true) {
int p=0;
String regex1 = "\\b(\\d+-\\d+)\\b";
Pattern p1 = Pattern.compile(regex1);
Matcher m1 = p1.matcher(str);
String[] card=new String[10000];
while (m1.find()) {
card[p]=m1.group(1);
p++;
}
Pattern numberpattern=Pattern.compile("(\\d+)-(\\d+)");
String regex4="\\b(\\d\\b)";
Pattern p4=Pattern.compile(regex4);
Matcher m4 =p4.matcher(str);
if(m4.find()) {
int num = Integer.parseInt(m4.group());
arr1[sum2]=num;
// System.out.println(arr1[sum2]);
}
x=0;
for(i=0;i<p;i++) {
Matcher numbermatcher = numberpattern.matcher(card[i]);
while (numbermatcher.find()) {
int count = Integer.parseInt(numbermatcher.group(1));
int score = Integer.parseInt(numbermatcher.group(2));
test[sum2][x]=new Test(count,score);
x++;
}
}
a1[sum2]=x;
sum2++;
}
else {
//String regex2="#A:(.+)$";
String regex2="#A:(\\d+)";
String regex3="\\b(\\d\\b)";
Pattern p2=Pattern.compile(regex2);
Matcher matcher1 =p2.matcher(str);
Pattern p3=Pattern.compile(regex3);
Matcher matcher3 =p3.matcher(str);
y=0;
if(matcher3.find()){
int num1= Integer.parseInt(matcher3.group());
arr2[sum3]=num1;
}
while (matcher1.find()) {
String answer1 = matcher1.group(1);
an[sum3][y] = new Answer(answer1);
y++;
}
a2[sum3]=y;
sum3++;
}
}
for(i=0;i<sum2;i++){
int sumScore=0;
for(j=0;j<a1[i];j++){
sumScore+=test[i][j].getScore();
}
if(sumScore!=100)
System.out.println("alert: full score of test paper"+arr1[i]+" is not 100 points");
}
int flag=0;
if(sum2>=sum3) {
int[] score=new int[100];
for(i=0;i<sum3;i++) {
int p=0,Sum=0;
for(j=0;j<sum2;j++) {
flag=0;
if(arr1[j]==arr2[i]) {
for(int m=0;m<a2[j];m++) {
for(k=0;k<sum1;k++) {
if(test[j][m].getCount()==ques[k].getnum()) {
boolean s=(ques[k].getstandardAnswer()).equals(an[i][m].getanswer());
System.out.println(ques[k].gettitle()+"~"+an[i][m].getanswer()+"~"+s);
if(s==true)
score[p]=test[j][m].getScore();
else
score[p]=0;
p++;
}
}
}
flag=1;
break;
}
}
if(flag==0) {
System.out.println("The test paper number does not exist");
break;
}
if(a1[i]>a2[i]) {
for(int t=0;t<a1[i]-a2[i];t++){
System.out.println("answer is null");
score[p]=0;
p++;
}
}
for(int t=0;t<a1[i];t++) {
if(t==0)
System.out.printf("%d",score[t]);
else
System.out.printf(" %d",score[t]);
Sum+=score[t];
}
System.out.printf("~%d\n",Sum);
}
}
else {
int[] score=new int[100];
for(i=0;i<sum3;i++) {
int p=0,Sum=0;
for(j=0;j<sum2;j++) {
if(arr1[j]==arr2[i]) {
for(int m=0;m<a2[j];m++) {
for(k=0;k<sum1;k++) {
if(test[j][m].getCount()==ques[k].getnum()) {
boolean s=(ques[k].getstandardAnswer()).equals(an[i][m].getanswer());
System.out.println(ques[k].gettitle()+"~"+an[i][m].getanswer()+"~"+s);
if(s==true)
score[p]=test[j][m].getScore();
else
score[p]=0;
p++;
}
}
}
}
}
if(a1[i]>a2[i]) {
for(int t=0;t<a1[i]-a2[i];t++) {
System.out.println("answer is null");
}
}
for(int t=0;t<a2[i];t++) {
if(t==0)
System.out.printf("%d",score[t]);
else
System.out.printf(" %d",score[t]);
Sum+=score[t];
}
System.out.printf("~%d\n",Sum);
}
}
}
}
这次的作业完成度只有百分之九十,因为我还有最后一个测试点没有过(测试点:各种情况都有)。而因为我的耦合度很高,所以问题也很多
- 首先for循环中数组最后总是会指向null,这就让我在修改上的难度大大提升,经常会看不出哪里错了。
- 然后就是有一个就是没有答案时,题目要求输出“answer is null”,这条语句有时输出不了。
3.答案判断程序-3(第三次作业)
这次作业的难度又增加了不少,这次我修改了一下方法,采用了HashMap和ArrayList,用它们来增加试卷中的题目数量。同时我添加了学生类(用来存学生信息),试题类(用于存试卷中的题目信息)和答卷类(用来存试卷信息和处理试卷信息)。但即使是这样,我依然没有很好的完成这次作业。它到现在依然存在着很多问题。但因为没有清晰地测试点,这也就让我摸不着头脑,就像一只无头苍蝇一般在到处乱飞。
这次作业真正的让我认识到了面向对象的好处(这使所有的问题都区域化了,每个类只需要完成所对应的功能),但相对的,在这过程中遇到的问题也就变多了,这也是在所难免的。
- 其中让我十分崩溃的是,题目中提到试卷中的序号是题目的编号,而学生答案中序号只是表示试卷中第几道题(而不是题目的编号),这让我修改了好久,最后还是听别人说才知道。 * * 然后就是删除的题目和不存在的题目所输出的内容不一样,我总是顾此失彼,只能达到其一。
三、改进代码
对于我现在的代码需要改进的地方还很多。比如,它现在的耦合度还非常的高,Main类中的代码长度很长,没有很好的分配,做到职责单一。我将会进一步划分每个类的职责,优化自己的代码架构。还有就是我需要加一些注释,这样我代码看起来才会清晰,一段时间之后还能知道自己当时是怎么想的。这样使代码的可读性大大提高。
四、总结与收获 - 通过这次大作业,首先学会的就是正则表达式,体会到了他的效率是非常的高,泛用性也非常广。然后就是学会了使用起来很方便的HashMap与ArrayList,这两种方法中,我对HashMap的理解运用更熟练一点。最后就是了解到了面向对象的思维,即使现在还非常的不熟练,但在今后的学习中,我相信会变得越来越熟练。
- 通过这几个星期的作业,我体会到了java的复杂度,这也就需要我花费大量的时间去理解它,提前学习常用的一些方法,以便能够简化自己的代码,降低自己的压力。除了在学堂在线上的视频要认真看完以及课后习题写完外,还可以自己去找一些视频看,完善老师所没有涉及的内容。
- 最后就是第三次大作业中测试点不清晰(可能是想让我自己去找),这让我写的时候不清楚哪里有问题(有点无力了)。即使当时不给,但希望最后一周做总结的时候能够给出相对应的测试点,这样让我能够清楚自己哪里考虑不全,然后加以修改。