目录

前言

PTA第一次大作业总结

PTA第二次大作业总结

PTA第三次大作业总结

设计与分析

PTA第一次大作业的设计与分析

PTA第二次大作业的设计与分析

PTA第三次大作业的设计与分析

采坑心得

改进建议

总结

前言
在经历了将近两个月的java这一面向对象编程语言的学习后,我学到了很多新的概念,例如:对象、类、多态、继承等等,对于编程也有了全新的理解。通过这三次大作业的实践,我体会到了,在java编程中,我们更像一个设计师,在编程前要先进行设计,这样能让在实现功能时思路更加清晰。接下来是我对这三次大作业的总结。

PTA第一次大作业总结
第一题:7-1 设计一个风扇Fan类
1.该题目所涉及到的知识点

类与对象:题目要求设计一个 Fan 类来表示风扇。类是对象的蓝图,定义了对象的属性和行为。在这个例子中,Fan 类包含了风扇的各种属性和方法。通过创建 Fan 类的对象,我们可以表示具体的风扇实例。

构造方法:Fan 类有两个构造方法,分别为有参构造和无参构造。有参构造必须要输入所有对应参数才能创建对象,而无参构造则不需要。

私有成员以及访问方法:Fan类的成员都是私有的,所以我们要在类中提供getter与setter方法,来供外部访问成员。

方法重写:Fan中重写了tostring的方法,以便外部可以直接用print来输出正确的格式。

2.题目难度

简单

第二题:7-2 类和对象的使用
1.该题目所涉及到的知识点

与第一题类似,涉及到了类与对象的基本概念,构造方法的使用,私有成员以及访问方法以及方法重写。

2.题目难度

简单

第三题:7-3成绩计算-1-类、数组的基本运用
1.该题目所涉及到的知识点

与第一题类似,涉及到了类与对象的基本概念,构造方法的使用,私有成员以及访问方法以及方法重写。

数组:该题用到了Student类的数组,用于存放Student类的对象。

类型转换:该题用到了Integer.parseInt()方法,用于将控制台中输入的字符串类型的数据转化为int类型。

输入控制:通过String[] s = str.split("\s"),来接收由空格隔开的数据。

2.题目难度

简单

第四题:7-4成绩计算-2-关联类
1.该题目所涉及到的知识点

与上一题类似,涉及了类的构建以及Student类的数组的使用,除此之外,还使用了方法用于计算成绩例如:
public void generateChinese(int pinshi,int qimo)
{
this.chinese = (int)(pinshi0.4+qimo0.6);
}
这个方法就是用于计算中文的最终成绩。

2.题目难度

简单

第五题:7-5 答题判题程序-1
1.该题目所涉及到的知识点

多个类的设计:该题目需要我们先做好类的设计,画好类图,设计好各个类的分工和合作。

正则表达式与模式匹配:该题目涉及到了正则表达式的使用以及 Pattern和 Matcher类的使用,通过模式匹配,来获取特定的信息,例如:
通过String answer = "#A:\s*([^\s]+)"来匹配 #A:2,#A后的答案。

输入的流程控制:题目会输入多行信息,最后以end表示结束输入。我们要通过流程控制,来读取需要的信息,存入对应对象中。

2.题目难度

中等

PTA第二次大作业总结
第一题:7-1 手机按价格排序、查找

1.该题目所涉及到的知识点

接口的使用:为了使用Collections.sort(phones)的方法,我们要在Mobilephone类中实现Comparable的接口:
@Override
public int compareTo(MobilePhone other) {
return Integer.compare(this.price, other.price);
}

2.题目难度

简单

第二题:7-2求圆的面积(类与对象)

1.该题目所涉及到的知识点

和前面的题目类似

2.题目难度

简单

第二题:7-3Java类与对象-汽车类

1.该题目所涉及到的知识点

和前面的题目类似

2.题目难度

简单

第三题:7-4 答题判题程序-2

1.该题目所涉及到的知识点

输入流程控制,输出流程控制,类的设计。

错误判断:该题目可能会出现一些错误的输入,如输入试卷不存在,题目总分不到100,回答数量超出题目数量等。我们要能够判断这些错误并输出对应信息。

2.题目难度

中等

PTA第三次大作业总结

第一题:7-1 面向对象编程(封装性)

1.该题目所涉及到的知识点

与前面的题目类似

2.题目难度

简单

第二题:7-2日期类的基本使用

1.该题目所涉及到的知识点

日期类的使用:该题目我们要运用到LocalDate、Period、DateTimeFormatter以及DateTimeParseException这一类和日期有关的类。

2.题目难度

简单

第三题:7-3 答题判题程序-3

1.该题目所涉及的知识点

多个类的分工设计:该题目所涉及的类的分工较为复杂,我们需要在开始前进行较为系统的设计。

错误判断:在题目的输入中,会出现多错误输入的情况,我们需要判断输入的错误,并进行相应提示。

2.题目难度

困难

设计与分析
在做大作业之前,我们首先要对题目进行分析,接下来是我在做大作业之前,对题目的分析。

PTA第一次大作业的设计与分析

1、题目分析与类的设计

本题要求设计一个小型测试程序,能够读取题目信息和答题信息,并根据标准答案判断答题结果。根据题目输入样例我们可以了解到,输入信息大致可以包括三种:1、和题目有关的题目信息 2、回答有关的回答信息。所以我们可以设计两个类:题目类与答案类,用于接收这最基础的题目和答案信息如:题目序号、答案序号、题目问题、正确答案、题目回答等;由于题目和对应的回答不只一个,所以我们需要用一个试卷类,来存放所有题目,用一个答卷类,来存放所有对应的回答;最后我们设计一个卷子类,来存放答卷和试卷,这样方便我们进行答案判断和输出格式的控制;除此之外,我还设计了一个Gnerate类,用于接收输入信息,通过模式匹配来将对应信息放入对应的对象中。

2、类图

如图:daan类中的成员有:回答,答案对应的题目序号,答案的正确性。 题目类中的成员有:题目序号,具体题目,正确回答。 试卷类的成员有:题目数组,题目数量。 答卷类的成员有:答案数组,回答数量。卷子类成员有:试卷,答卷,方法有:判断答案的准确性以及输出信息。

3、具体流程

本题的流程较为简单,我就口头讲述一下:先接收一行数据,通过模式匹配匹配该行中的对应信息,以下为模式匹配的正则表达式:
String RegexQ = "#Q:\s([^#]+?)\s(?=#|$)";//获取问题
String RegexN = "#N:\s(\d+)";//获取问题数的表达式
String RegexA = "#A:\s
([^\s]+)";//获取正确答案
当匹配到对应信息后我们将其存入对应的对象之中,最后再调用答卷类中的MyPrint方法,按照题目要求打印出对应信息。

PTA第二次大作业的设计与分析

本题目在上一题的基础上,增加了许多内容,该题目输入会输入多张试卷的信息,每张纸卷中有多个题目;而答卷也同样如此,题目会输入多张答卷,正常输入情况下,每张答卷都有对应的试卷,答卷中的回答都有试卷中的题目与之对应。除此之外,题目中还会有错误的输入,例如:总分不到100要有提示,答卷号对应的试卷不存在,答卷中的答案对应的题目不存在等。我们要通过程序来控制这些流程。

1、题目分析与类的设计

我们的类可以按照之前的设计来,但需要进行一些更改:由于会输入多张试卷,所以我们要在试卷类的成员中加上试卷编号,同理,答卷也要加上答卷编号;除此之外,卷子类的成员要改为试卷数组和答卷数组,以及答卷数量和试卷数量;题目中要记录题目得分,答卷要记录题目总分和题目总得分。

2、类图

如图所示,和之前所说相同,我们在第一题的基础上加了许多内容:在答卷类中添加了答卷编号,在试卷类中添加了试卷编号,试卷总分和试卷得分。

3、具体流程

输入流程:

先是接收一行数据,判断开头#后的字母为什么,若为N,则说明之后跟着的是题目信息,我们就用一个timu类型的数组接收该题目的信息;若为T,则说明输入的是试卷信息,我们用试卷类型的成员调用CreatShijuan方法来接收题目的信息;若为S,则同理,直到匹配到end后,结束输入流程。

输出流程:

这个流程我用了三层循环,较为复杂,所以在流程图上就没有体现其中循环的过程。我们先是用第一层循环匹配试卷号和答卷号,若匹配上了,则第二层循环匹配答案号和题目号,当全都匹配上了之后,再用第三层循环判断答案是否和正确答案一致,若一致,则加上分数。最后再按照题目的格式进行输出。

PTA第三次大作业的设计与分析

1、题目分析与类的设计
第三次作业在第二次的基础上添加了许多内容:1、添加了学生信息,每张答卷有对应的学号,学生有姓名和学号信息。2、添加了题目的删除,我们可以删除已存在的题目。3、输入中会出现许多错误输入的情况,例如:答卷的学号是不存在的学生、答卷中回答了以删除或者不存在的问题、输入中存在错误格式的输入.....所以我添加了一个错误类,通过模式匹配,得到非正确的输入,最后保存起来,在题目类中增加了一个新的成员:isdeleted来判断改题目是否被删除了。

2、类图

如图所示,相较于上一次作业,我添加了许多内容,就和之前介绍中的一样,我添加了学生类,添加了错误类,以及在卷子类和试卷类中添加了许多方法。

3、具体流程

输入流程:

在上次作业的基础上,我添加了题目删除和错误获取的逻辑,当我们匹配到了#后错误的字母,我们就将那一段信息传给错误判定的方法中。

踩坑心得

1、要先设计再开始写代码

再第三次大作业中,我看到与之前第二次作业题目十分类似,于是我就没有进行详细的设计,直接开始着手编程,于是我就写出来了一个四层的嵌套循环,以及无数的分支结构,最后导致牵一发而动全身,无法继续修改下去了,代码如下:

点击查看代码

 for (int i = 0; i < this.numberD; i++)
        {
            int flag = 0;//判断有没有匹配上的
            for (int j = 0; j < this.numberS; j++)
            {
                //答案卷号和试卷号匹配上了
                if(this.shijuans[j].getNum() == this.dajuans[i].getNum())
                {
                    shijuan s = shijuans[j];
                    dajuan d = dajuans[i];
                    int score=0;
                    flag = 1;

                    //如果试卷的题目数量大于答卷的题目数量啦
                    if(s.getNumber()>=d.getNumber())
                    {
                        for (int k = 0; k < d.getNumber(); k++)
                        {
                            //如果题目被删除
                            if(s.getTimu()[k].IsDelete())
                            {
                                System.out.println("the question "+k+1+" invalid~0");
                            }
                            //如果没被删除
                            else
                            {
                                //如果答对了
                                if(s.getTimu()[k].getCorrectAnswer().equals(d.getDanas()[k].getAnswer()))
                                {
                                    //加分
                                    score+=s.getTimu()[k].getScore();
                                    d.getDanas()[k].setScore(s.getTimu()[k].getScore());
                                    System.out.println(s.getTimu()[k].getTest()+"~"+d.getDanas()[k].getAnswer()+"~true");
                                }
                                //答错
                                else
                                {
                                    System.out.println(s.getTimu()[k].getTest()+"~"+d.getDanas()[k].getAnswer()+"~false");
                                }
                            }

                        }
                        //调整输出格式,当题目数量大于答案数量时,要输出
                        for (int k = 0; k <s.getNumber()-d.getNumber(); k++) {
                            System.out.println("answer is null");
                        }
                        //匹配姓名:
                        SearchStudent(this.dajuans[j].getXuehao());
                        for (int a = 0; a < d.getNumber(); a++) {
                            System.out.print(d.getDanas()[a].getScore());
                            if(a!= d.getNumber()-1)
                            {
                                System.out.print(" ");
                            }
                        }
                        for (int k = 0; k <s.getNumber()-d.getNumber(); k++) {
                            System.out.print("0");
                        }
                        System.out.print("~"+score);

                    }

                    else
                    {
                        for (int k = 0; k < s.getNumber(); k++)
                        {
                            //如果题目被删除
                            if(s.getTimu()[k].IsDelete())
                            {
                                System.out.println("the question "+k+1+" invalid~0");
                            }
                            //如果没被删除
                            else
                            {
                                //如果答对了
                                if(s.getTimu()[k].getCorrectAnswer().equals(d.getDanas()[k].getAnswer()))
                                {
                                    //加分
                                    score+=s.getTimu()[k].getScore();
                                    d.getDanas()[k].setScore(s.getTimu()[k].getScore());
                                    System.out.println(s.getTimu()[k].getTest()+"~"+d.getDanas()[k].getAnswer()+"~true");
                                }
                                //答错
                                else
                                {
                                    System.out.println(s.getTimu()[k].getTest()+"~"+d.getDanas()[k].getAnswer()+"~false");
                                }
                            }
                        }
                        for (int k = 0; k <s.wuxiaoNum; k++) {
                            System.out.println("non-existent question~0");
                        }
                        //匹配姓名:
                        SearchStudent(this.dajuans[j].getXuehao());
                        for (int a = 0; a < s.getNumber(); a++) {
                            System.out.print(d.getDanas()[a].getScore());
                            if(a!= d.getNumber()-1)
                            {
                                System.out.print(" ");
                            }
                        }
                        System.out.print("~"+score);
                    }
                }
            }
            if(flag==0)
            {
                System.out.println("The test paper number does not exist");
            }
        }

俗话说磨刀不误砍柴功,我们在写题目之前,应该要先进行详细的设计,今后我会吸取这几次大作业的教训

2、在用sc.next()方法时,要记得消除换行符

3、本题中对于题目,答卷等数据的存储都是用的数组形式来存的,但是这种数据结构是有缺陷的,在删除和长度扩充等操作上比较麻烦,可以在今后采取ArrayList等容器来存储

改进建议

1.在对字符串进行操作时,对于频繁的字符串操作,应该使用StringBuilder或StringBuffer类来提高效率。
2.对于代码异常情况,使用try-catch语句块来捕获和处理异常,以保证程序的稳定性和可靠性。
3.学习常用的类和库,如java.util、java.io等,并实践使用它们来解决实际问题。
4.多学习map类和list类,不要只用数组来解决问题
5.进行代码编写前,先进行类图设计和部分流程的分析,磨刀不误砍柴工。

总结

通过本阶段的三次题目集的练习,学会了使用增强for循环和if-else条件语句来实现程序的控制流程,包括遍历数据、判断条件和执行不同的操作;学会了创建类、定义属性和方法,以及使用类创建对象并操作对象的属性和方法;学会了使用字符串操作的方法,如分割、替换和拼接字符串,以及比较字符串和提取子字符串;学会了如何利用正则表达式来进行模式匹配,提取我们需要的字符串;除此之外,我还学会了如何进行类的设计以及如何画类图。
需要进一步学习之处:异常处理:在给定的代码示例中,并未完全处理输入错误或无效数据的情况。学习如何使用try-catch块来捕获和处理异常,以提高程序的健壮性。StringBuilder类的使用:题目中有许多对于字符串的操作,但我都只是用纯粹的算法解决,没有用到这么好用的类。了解面向对象编程原则:学习如何设计良好的类和对象,并遵循面向对象编程的原则,如继承和多态。这将使代码更加可维护、可扩展和可重用。更多的Java核心概念和库:继续学习Java的核心概念,如继承、多态、接口等,并了解常用的Java库和框架,如集合框架、IO操作、日期时间处理等。

总体而言,我已经掌握了一些Java编程的基础知识和技巧,但仍有许多内容需要进一步学习和研究。通过不断练习、听讲,阅读文档和参考优秀的代码示例,我相信可以不断提升自己的编程能力和解决问题的能力。