oop前三次作业总结(第一次Blog)

oop前三次作业总结(第一次Blog)

目录

一、前言

二、设计与分析

三、踩坑心得

四、改进建议

五、总结

一、前言

1、第一次作业

这五道题运用了类和对象的基础知识以及类、数组的基本运算,用类对象封装数据完成题目要求,以语法为主,这几道题还算比较基础,写起来也不会有反复琢磨某个测试点的情况,在做题前还没有正式进入类的学习,只在网上看了一些相关知识的介绍,所以对类的掌握度也不是很好,但是相比之下难度不大。

2、第二次作业

共有四道题,首先第一题要求该类实现Comparable接口,重写compareTo方法,通过Collections类的sort方法对链表中的对象按照price升序排序,Collections是Java已经定义好的类,可以直接使用。第二题,在类里定义方法进行计算。第三题比较简单,运用了类和对象的基础知识。最后一题比较困难,需要运用多个类,并且在第一次作业最后一题的基础上要求增补或者修改内容,实现起来相比第一次会困难一点。

Comparable接口:

Comparable是排序接口。若一个类实现了Comparable接口,就意味着该类支持排序。实现了Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序。

Collections类:

Collections类是Java提供的一个操作List,Set和Map等集合的工具类。Collections类中提供了一系列操作集合的静态方法,使用这些方法可以实现对集合元素的排序、查询、修改等操作。

3、第三次作业

第一题是类的封装性,已经给出部分代码,只需设计类。第二题是日期类的基本使用,需要去网上找资料学习,但是运用起来还是会比较方便。最后一题对我来说比较困难,并且在第二次作业最后一题的基础上要求删除内容,好几个测试点也不是很明确,代码完成后发现不知从何处修改,还是要琢磨很久的,也体现出了举一反三的能力。

二、设计与分析

关于SourceMontor:

  • Lines: 指的是代码总行数
  • Statements:语句的行数,语句是以分号结尾的。这个C中有所不同。
  • Percent Branch Statement:分支数占总语句数的百分比
  • Method Call Statement:方法调用语句数
  • Percent Lines with Comments:注释语句占总语句数的百分比
  • Classes and Interfaces:类和接口数
  • Methods per Class:每个类平均包含函数个数
  • Average Statements per Method:每个函数平均包含的语句个数
  • 函数复杂度(Function Complexity)复杂度指1个函数可履行路径的数目,以下语句为复杂度的值贡献1:if/else/for/while语句,3元运算符语句,if/for/while判断条件中的"&&"或“||”,switch语句,后接break/goto/ return/throw/continue语句的case语句,catch/except语句等。对应有最大复杂度(Max Complexity)和平均复杂度(Avg Complexity)

  • 函数深度(Block Depth):函数深度是函数中分支嵌套的层数。对应有最大深度(Max Depth)和平均深度(Avg Depth)。

  • Line Number of Complex Method:最复杂函数的行号(最复杂指的是McCabe复杂度值为最高)
  • Maximum Complexity:该类中最复杂函数的复杂度(最复杂指的是McCabe复杂度值为最高)
  • Line Number of Deepest Block:最深层语句块的行号

1、第一次作业

类图:

Contest类用来放题目信息(包括编号,问题,标准答案),Test用来存放学生的答卷(包括编号,题目信息)。

设计得很简单,只适用于第一次作业,这也导致后面做题有问题。

设计分析:

Main函数里的复杂度相比其他两个类的较高,for循环较多。

2、第二次作业

类图:

仍然和第一次作业的类设计一样,这也让我自己踩了一个大坑(不听老师言,吃亏在眼前),类分得过于粗略,在Main函数里会运用多个for循环,增加复杂度。过分地依赖Main函数实现大部分方法会让代码变得很混乱,导致后面自己也看不清写的是什么东西。

设计分析:

可以看出Main函数里的复杂度仍然时最高的,并且还增加了很多,因为我的类太过粗略,很多方法都会放在Main函数里,这也使Main里添加更多的if/else/for·······语句,使复杂度提高。

3、第三次作业

类图:

认识到第一次和第二次的错误后,我重新设计类,AnswerPaper用来存放答卷信息(包括编号,学号,题目编号以及答题答案),Test用来存放试卷信息(包括编号,题目编号,题目分数),Question用来存放题目信息(题目编号,题目,标准答案),Students用来存放学生信息(包括所有学生学号,所有学生姓名),DeleteInformation用来存放删除信息(包括删除的字符,删除的编号)

但是类与类之间并没有链式的关联结构,所以编写的时候会有点混乱,而且类分得越细会让逻辑更加清晰,写起来也不会变得很混乱。

设计分析:

因为Main函数利用正则表达式来判断信息,所以if/else语句偏多,复杂度自然也就更高了。

Main函数:

查看代码
 public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		LinkedList<Question> question = new LinkedList();
		LinkedList<Test> test = new LinkedList();
		LinkedList<AnswerPaper> answerpaper = new LinkedList();
		Students stu = new Students();
		LinkedList<DeleteInformation> delete = new LinkedList();
		String[] regex = { "^#N:\\s*(\\d+)\\s*#Q:\\s*(.*?)\\s*#A:\\s*(.*)",
				"^#T:\\s*\\d+\\s*((\\d+\\s*-\\s*\\d+\\s*)+)$", "^#S:\\s*\\d+\\s*\\d+\\s*(.*?)$",
				"^#X:\\s*\\d+\\s(.*?)+(?:-\\d+\\s(.*?)+)*$", "^#D:\\s*N\\s*-\\s*\\d+\\s*$", };

		Pattern pattern1 = Pattern.compile(regex[0]);
		Pattern pattern2 = Pattern.compile(regex[1]);
		Pattern pattern3 = Pattern.compile(regex[3]);
		Pattern pattern4 = Pattern.compile(regex[2]);
		Pattern pattern5 = Pattern.compile(regex[4]);
		while (true) {
			String str = sc.nextLine();
			if (str.contains("#N")) {
				Matcher matcher1 = pattern1.matcher(str);
				if (!matcher1.find()) {
					System.out.println("wrong format:" + str);
					continue;
				}
				Question que = new Question(str);
				question.add(que);

			} else if (str.contains("#T")) {
				Matcher matcher2 = pattern2.matcher(str);
				if (!matcher2.find()) {
					System.out.println("wrong format:" + str);
					continue;
				}
				Test te = new Test(str);
				test.add(te);
			} else if (str.contains("#X")) {
				Matcher matcher3 = pattern3.matcher(str);
				if (!matcher3.find()) {
					System.out.println("wrong format:" + str);
					continue;
				}
				stu = new Students(str);
			} else if (str.contains("#S")) {
				Matcher matcher4 = pattern4.matcher(str);
				if (!matcher4.find()) {
					System.out.println("wrong format:" + str);
					continue;
				}
				AnswerPaper ans = new AnswerPaper(str);
				answerpaper.add(ans);
			} else if (str.contains("#D")) {
				Matcher matcher5 = pattern5.matcher(str);
				if (!matcher5.find()) {
					System.out.println("wrong format:" + str);
				}
				DeleteInformation de = new DeleteInformation(str);
				for (int j = 0; j < question.size(); j++)
					if (de.getNum().equals(question.get(j).getQuestionNum()))
						question.get(j).setQuestion(null);
			} else if (str.equals("end"))
				break;
			else
				System.out.println("wrong format:" + str);
		}
		for (int i = 0; i < test.size(); i++)
			if (!test.get(i).ifOnehundred())
				System.out.println("alert: full score of test paper" + test.get(i).getTestNum() + " is not 100 points");

		for (int i = 0; i < answerpaper.size(); i++) {
			AnswerPaper an = answerpaper.get(i);
			Test t1 = an.isTest(test);
			if (t1 == null)
				System.out.println("The test paper number does not exist");
			else {
				int flag = 0;
				an.checkNum(t1, question);
				for (int j = 0; j < stu.getSname().size(); j++)
					if (stu.getSid().get(j).equals(an.getSid())) {
						System.out.print(stu.getSid().get(j) + " " + stu.getSname().get(j) + ": ");
						an.checkScore(t1, question);
						flag = 1;
					}
				if (flag == 0)
					System.out.println(an.getSid() + " not found");
			}
		}

	}

}

 

最后,我认为我的类设计稍有欠缺,部分代码会很混乱,没有加注释所以最后根据测试点找错的时候会忘记代码所表示的什么,这也浪费了许多时间在这方面上。

三、踩坑心得

1、第一次作业

类设计及类间关系设计,不能取巧采用内部类的方式破坏类的封装性。没有听老师说的,我采用了内部类的方式,甚至有些题为了方便,类成员都采用可见性修饰符(public),这个问题还是比较大的。其次就是正则表达式,没有掌握好如何表达,写错后会报非零返回的错,有时候存储信息出错也会时答案错误。

第一次作业最后一题(不正规)代码:

查看代码

import java.util.Scanner;
public class Main{
    public static class Contest{
        private int num;
        private String question;
        private String standardAnswer;
        public Contest()  { }
        //getter
        public int getNum()
        {return num;}
        public String getQuestion()
        {return question;}
        public String getStandardAnswer()
        {return standardAnswer;}
        //setter
        public void setContest(int num,String question,String standardAnswer){
            this.num=num;
            this.question=question;
            this.standardAnswer=standardAnswer;
        }
        //判断答案
        public boolean trueOrFalse(String answer){
            return this.standardAnswer.equals(answer);
        }
    }
    public static class Test{
        int sum;
        Contest[] contest=new Contest[1000];
        public Test() { }
        public void setTest(int sum,int i,int num,String question,String standardAnswer)
        {
            this.sum=sum;
            this.contest[i]=new Contest();
            this.contest[i].setContest(num,question,standardAnswer);
        }
        //判断number
        public boolean checkTitle(int i,Contest contest){
            return contest.num==i;
        }
        //保存题目
        public void saveContest(int i,int j,Contest contest){
            boolean o=checkTitle(i,contest);
            if(o)
                this.contest[i-1].setContest(contest.num,contest.question,contest.standardAnswer);
        }
    }
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        Test test=new Test();
        test.sum=n;
        int m=0;
        String[] con=new String[n+3];
        while(sc.hasNextLine()){
            con[m]=sc.nextLine();
            if(con[m].equals("end"))
                break;
            m++;
        }
        String[] answer=con[m-1].split("\\s?#[NQA]:\\s?");
        String[][] cont=new String[n][4];
        int[] num=new int[n];
        String[] question=new String[n];
        String[] standardAnswer=new String[n];
        //分割
        for(int i=0;i<n;i++)
            cont[i]=con[i+1].split("\\s*#[NQA]:\\s*");
        //将字符转化为数字
        for(int i=0;i<n;i++)
            num[i]=Integer.parseInt(cont[i][1]);
        //分割question
        for(int i=0;i<n;i++)
            question[i]=cont[i][2];
        //分割standardAnswer
        for(int i=0;i<n;i++)
            standardAnswer[i]=cont[i][3];
        Contest[] contest=new Contest[n];
        for(int i=0;i<n;i++){
             contest[i]=new Contest();
            contest[i].setContest(num[i],question[i],standardAnswer[i]);
             test.setTest(n,i,contest[i].num,contest[i].question,contest[i].standardAnswer);
         }

        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                test.saveContest(i+1,j,contest[j]);
        //判断对错
        boolean[] yesOrNo=new boolean[n];
        for(int i=0;i<n;i++)
            yesOrNo[i]=test.contest[i].trueOrFalse(answer[i+1]);
        for(int i=0;i<n;i++)
            System.out.println(test.contest[i].question+"~"+answer[i+1]);
        for(int i=0;i<n;i++)
        {
            if(i==n-1)
                System.out.print(yesOrNo[i]);
            else
                System.out.print(yesOrNo[i]+" ");
        }
    }
}

没有按照老师的要求进行,也为我下一次作业埋下了伏笔,后面题目的进行也让我比较迷糊。

2、第二次作业

第二次作业第一题就让我踩上了坑,在写这道题之前不了解Comparable接口,所以首先看题目的时候也晕头转向的,对于Java已定义的类也不是很清楚,还傻傻的自己去写一个Collections的类,后面经同学提醒后才恍然大悟。因为上一次PTA作业最后一题没有按照老师的要求设计类,最后写到头晕也没有把这道题写对,本来已经在第一次的基础上增加了很多东西,结果还是依然用两个类进行编写,这个就会导致有内容无法重复使用,只能使用一次,想用for循环但是被绕晕了(编译也救不了我),没有运用动态数组,最后想重写结果也没有时间了。

最后一题的测试点都是多试卷过不了,类设计不规范。

3、第三次作业

第二题依旧是Java已定义的类,写完后才发现我又又又踩坑了😓,第三题出现了审题的问题,题目给的和我自己写的会出现很大差别;其次就是正则表达式,有时候会因为一些小细节使数据存储错误,导致后面的答案出错;最后是逻辑的问题,因为一个for循环,就会使逻辑出错。

题目中明确给出不要混淆顺序号与题号,但是我还是用答案的题号与试卷中的题号进行比较。

四、改进建议

  • 不要按照自己的想法去做题,最好是跟着老师给出的思路,不然会走很多弯路。
  • 做题时需要认真审题,格式、要求、设计都要好好看。
  • 在做题前需要边读题边思考,有一个清晰明确的思路后再开始编写,不然写了一大半发现思路错误后,只能推翻重写了,不仅浪费时间,还影响了自己的思路。
  • 类设计是最需要改进的,要学会运用链式的关联结构,而不是单纯的类关系,并且类要符合单一职责原则进行设计。
  • 正则表达式也要更进一步的学习。

五、总结

这学期才开始了解面向对象程序设计,所以一开始对于怎么写,以及Java语法有点不太适应,刚开始对Java一窍不通,就着上学期学了皮毛的C语言(对于我来说)去看了看新发的Java书,看了一点发现Java和C语言的语法比较类似,以为Java不是很难,又因为前几次布置的作业都是上学期写过的,所以刚开始以为会比较顺利。但是当我开始做第一次PTA大作业后,发现会有点卡壳,后面两次大作业也是做得晕头转向的。这三次作业难度层层递进,设计也越来越复杂,我也从中学到了许多知识:类和对象的基础知识以及类、数组的基本运算,用类对象封装数据完成题目要求,Comparable接口,Java类库,动态数组······也初步认识到了类的设计技巧:1. 保证数据私有;2. 对数据初始化;3、不要在类中使用过多的基本类型(用其他的类代替多个相关的基本类型的使用,这样会使类更加易于理解且易于修改。)4、将职责过多的类进行分解;5、类名和方法名要能够体现它们的职责。由于我做题时只想过测试点,完全忽略了类设计,所以对于我自己来说的话,类该如何设计是需要进一步学习和研究的,还有在测试的过程中,也要养成举一反三的好习惯。最后也希望老师可以在作业结束后发布出完整代码让我们参考学习。

posted @ 2024-04-21 15:39  桃_YYH  阅读(18)  评论(0编辑  收藏  举报