对Java题目集4-6的总结性blog
一、前言:
这三次题目集相较于前三次的题目集的难度有所降低,但是还是有一些新的较难的内容需要我们自己去掌握!
要我们自主去学习比如在这次题目中所涉及到的知识点就有:数组的多重运用、正则表达式、哈希数组、类的继承、方法的重写以及多态的使用………
题量相较于以前的题目集也有所减少,难度稍微的降低了许多!
其中重点强调的是正则表达式的运用和多态!尤其是多态的运用,多态是Java语言的灵魂所在,在Java中封装、继承、多态……在以前的题目集中,我们都或多或少的碰到过,那么在这次的题目集中,我们就重点的学习一下多态吧!
------------------------------------------------------------------------------------------------------------------------------------------------------------------
二、设计与分析:
(1) 题目集4(7-2)、题目集5(7-4)两种日期类的聚合设计的优劣比较


解题分析:从两个题目所给出的要求我们可以看出,他们所要实现的功能是一样的。但基于不同的聚合类来实现,那我们现在先根据它的题目要求对应不同的类图来做出分析。
- 求下n天
- 求前n天
- 求两个日期相差的天数
题目集7-2所给出的类有主类main类、Day类、Month类、Year类DateUtil类,它们一一对应聚合关系。
题目集7-5所给出的类有主类main类、Day类、Month类、Year类DateUtil类,相较于7-2,7-5对类的运用更加的灵活,它把类的分工实行的非常明确,不会把所有的功能实现都放在一个DateUtil类里,而显得main类空荡荡,实际上main类可以起到一种对于各个类的方法的调用,起到一种主观大局的作用,而7-2的类图的实现,就没有做到这一点。
a.我们先来对这两个题目的Main类来进行分析:
我们可以根据大致的源码看到

7-5的main类主要有switch-case语句组成,而7-2的main语句则较为简单,因为大多数的功能实现都在DateUtil类中实现,使得DateUtil的类较为繁琐,甚至于有时会造成计算错误。那么此时我们可以看到7-5基本分工十分明确,不会有一些可避免的错误发生,同时代码量也减少了不少。解题思路也更加明确。
b. 那么接下来我们就来讨论一下这道题目的一些较为难处理的地方
我们根据题目所给的测试点可以摸索出几个较为较为难发现的点。

首先它有几个测试点是一定会考察到的:
- 闰年
- 闰年的二月
- 非闰年的二月
- 跨年、月测试
其中要注意的是算法一定要尽可能的精简,比如把if-else多用其他可替换的语句替换,加快计算速度,防止运行超时,我们早点通过这种训练,对以后的我们也会有很大的帮助!
基于代码的实现,这里不做过多的介绍,比如对闰年的判断,对年月日的计算,千人千
份答案,这里不分对错,每个人对于这些算法的理解,有可能是有自己的独到见解的。且这次的对于日期类的题目我们以早就熟练,并未涉及到过多的性的知识点,比如正则与数组类!
所以同学们对于这种题应该得心应手了。
(2) 题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
题目集4(7-3)

解题分析:我们读题可以发现,这道题主要用到的是继承的方法,那么我们想想继承中用到的中最多的就是对与方法的重写,那么在这里先根据PowerDesigner生成的类图来做出分析

其中我们创建了Shape类、Circle类、Ball类、Rectangle类、Box类。其中Shape类中设计的非常简单,只有一个返回面积的方法
class Shape {
public double getArea(){
return 0.0;
}
而我们设计了Circle类、Ball类、Rectangle类继承与Shape类,而Box类继承与Rectangle类。这些类在自己的类中有自己私有的属性,比如在Circle类中就有radius属性,这是Circle类特有的属性,而后,我们在每个类中根据图形的特性,分别重写了题目它们的求面积的方法
Circle类:
public double getArea() {//求圆的面积
return Math.PI * radius * radius;
}
Ball类:
public double getArea() {
return 4 * Math.PI * radius*radius;
}
Rectangle类:
public double getArea() {
return width * length;
}
Box类:
public double getArea() {
return length * width * 2 + length * height * 2 + width * height * 2;
}
然后我们只需在主方法中创建类,并且调用它们的方法进行输出即可。
在题目集4中只用到了类的继承与封装,对于同学们来说比较好使用。技术要求不高,那么我们来看看题目集6是否难度增加了呢……
题目集6(7-5)
参考题目集04中7-3中图形类的继承层次结构,题目集6重点研究平面图形相关的处理方法。图形类的继承层次结构如下图所示。

相较于题目集4,题目集6的难度系数大概是题目集4的double,我们根据题目可知:

解题分析:参考题目集4,大体上相同,但还加入了ArrayList的应用与抽象类,这里我们把Shape类抽象化,那么继承与它的一些类如Circle类Rectangle类、Triangle类等就需要把它们所继承的抽象类中的方法实体化,这里给出Shape类的相关代码以供参考
abstract class Shape{
public abstract double GetArea();
public abstract boolean Validate();
public void ToString(){}
}
我们可以看到,在Shape类中有三个抽象的方法,分别对应着它要实现的三个功能,求面积、求体积、输出格式。
继承于它的三个类必须得实现Shape中的方法,那么这些方法该如何实现呢,根据我们已有的数学知识,相对应不同的图形求面积求体积的方法应该很好实现,这里给出Rectangle类的代码以供参考
class Rectangle extends Shape{
private double length;
private double width;
Rectangle(){}
public Rectangle(double width,double length){
this.length=length;
this.width=width;
}
public double getLength() {
return length;
}
public double getWidth() {
return width;
}
public void setLength(double length) {
this.length = length;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double GetArea() {
return length*width;
}
@Override
public boolean Validate() {
if(width>0&&length>0)
return true;
else return false;}}
之后我们只需要根据题目要求输出即可!
题目集6(7-6)
接着我们来到题目集6的7-6
来看看题目吧~

根据题目给出的类图,我们可以十分容易的实现这些功能,尼玛在这一题中,我们可以看到题目的新要求:接口与多态
终于来到了Java 的灵魂之处,多态,我们知道,所谓的“多态”,简单的理解就是对象在不同情况下的不同表现,具体体现在定义和功能两个方面,简单的总结一下,多态可以用“三个定义和两个方法”来总结。三个定义分别是父类定义子类构建、接口定义实现类构建和抽象类定义实体类构建,而两个方法分别是方法重载和方法重写。在作用中我们采用的是抽象类定义、实体类构建的方式。即Shape为抽象类,Circle、Rectangle及Triangle为实体类。
以下给出源码以供参考:
import java.util.Scanner;
public class Main {
public static void main(String[] args)
{
Scanner in =new Scanner(System.in);
Circle circle=new Circle();
Rectangle
rectangle=new Rectangle();
double radius=in.nextDouble();
double width=in.nextDouble();
double length=in.nextDouble();
if(radius>0&&length>0&&width>0){
circle.setRadius(radius);
rectangle.setLength(length);
rectangle.setWidth(width);
double Area=circle.GetArea();
double Area2=rectangle.GetArea();
System.out.printf("%.2f\n",Area);
System.out.printf("%.2f",Area2);
}
else System.out.println("Wrong
Format");
}
}
interface GetArea{
public abstract
double GetArea();
}
class Circle implements GetArea{
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
Circle(){}
public Circle(double radius){
this.radius=radius;
}
@Override
public double GetArea() {
return Math.PI*radius*radius;
}
}
class Rectangle implements GetArea{
private double length;
private double width;
public double getLength() {
return length;
}
public double getWidth() {
return width;
}
public void setLength(double length) {
this.length = length;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double GetArea() {
return length*width;
}
}
从源码中我们可以得出,所要求的东西并不多,涉及到较新的东西也就是接口,不同于前面的两题,我们不需要创建一个Shape类,然后让我们的Circle等类继承与它,我们只需要让这些类都继承于一个GetArea接口,然后都根据自己的图形特性实现这个接口即可!有难度的地方不多,我们只需熟悉接口的应用以及多态即可!
(3) 对三次题目集中用到的正则表达式技术的分析总结
在这三次题目集中,或多或少的都涉及到了正则表达式的运用,
正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合, 组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。我们可以知道,在互联网运用中,正则起到了非常大的作用,比如密码的检验,网址的锁定,邮箱的匹配等等……
在次我们以题目集4中的7-1来分析一下正则比表达式

解题分析:
从题目可以看出,我们首先要对输入的数据进行检测,那么这里我们就需要用到正则表达式啦~~~~根据需求,写出相应的正则,检测数据是否合法,若输入的是非法数据-------》输出“Wrong Format”即可,若数据合法,那么则进行下一个步骤,对输入的数据进行处理,这里需要用到的仅仅是一些比较简单的计算,稍微了解一点数学常识即可。
那么下面给出一段代码示例,该段代码用于,简单的检测与分段,把数据分开成我们所需要的部分!!!
boolean validateDate(){
Pattern pattern = Pattern.compile("(.+)(?:\\|)(.+)(?:\\|)(.+)(?:\\|)(.+)(?:\\/)(.*)(?:\\|)(.*)");
Matcher matcher = pattern.matcher(date);
return matcher.find();
}
然后对数据进行对应的处理即可,最后一步便是输出了!但是虽然思路及其明确,对于代码的实现却还是有一定的难度的,所以还需要我们去充分的学习。
(4) 题目集5(7-4)中Java集合框架应用的总结分析
首先,我们来看到题目集5(7-4)的要求

从题目可以看到,要求我们对Java中出现的关键字进行统计,那么这里对应的一个非常简便的方法就是哈希数组啦~~~我们知道哈希数组是value-key模式的,一个value,一个key一一对应,那么我们就可以把一个个的关键字当成value,然后每一个key对应关键字出现的次数,这样就能很好的做出对于关键字的统计,下面给出关键字的模板:
String [] regex= { "abstract","assert","boolean","break","byte","case","catch",
"char","class","const","continue","default","do","double","else",
"enum","extends","false","final","finally","float",
"for","goto","if","implements","import","instanceof",
"int","interface","long","native","new","null","package",
"private","protected","public","return","short","static",
"strictfp","super","switch","synchronized","this","throw",
"throws","transient","true","try","void","volatile","while"
};
利用该模板可统计该关键字,然后对输入的信息首先进行预处理,接着把它分成一个字符串数组,然后与我们关键字数组一一对应,若能匹配到,则key+1,然后经过统计,输出对应的关键字与key即可!
我们通过该题目集可以学习到Hash-Map数组,体会到它的多种用法,它不仅可以是String-Int型,更可以是多种形态,只要能想像到都行。希望后面会对它进行更深入的学习。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
采坑心得:
在这次的题目集中,我们可以发现有许多的测试点,甚至无论如何都无法通过,尤其是求与日期相关的那一系列题目,很多奇怪的测试点,在请教同学后,才发现,欸居然是这个不对,所以我们在遇到问题自己无法解决时,自己一个人干想的话,效率及其的低,那么就需要我们求助同学了。
下面我们来看看一些及其难过的测试点:

其中这个日期测试点,真的有许多的坑等着我们去跳,比如在某一年的下N天,我们首先要判断,这一年是否为闰年,并且在下N天中,是否有超过年份的,然后还得考虑是否需要那一年就是闰年,是否超过2月,这一些的东西,我们都得考虑在内,那么这时编译器的Debug调试就非常的有用了 ,我们可以用debug查看到底时在哪一个类或者哪一个方法体中出现了问题,然后我们接着去修改。
要知道,写一个程序,并不是说写完了就好了的,后续的调试以及维护是非常重要的,然后我们所需的便是无尽的耐心……与调节好情绪,要知道调了半夜也调不出一个程序是常有的事。所有首先要做的就是保持冷静……接着继续调试。总会找到bug!
---------------------------------------------------------------------------------------------------------------------------------------------------------------
改进建议:
老师上课讲的非常的好,基本上对很多的知识点都讲的非常的细致,然后我们还有中国大学Mooc作为我们网上的学习平台,供我们在课余的时间学习,对我们的学习起到了非常大的帮助,然后如果有建议的话,那就是,pta的题目集的难度似乎下降了很多,希望还是可以有难度一点,然后有挑战性一点!
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总结:
在这次的题目集里,我们又掌握了比上一个题目集更多的知识点,比如上一个题目集有的继承与方法的重写,在这个题目集中又出现了一次,可以作为对继承的复习,然后还学习了一些新的东西,比如多态的使用,与正则表达式的复习,还有Array List的运用。
其中出现次数最多的便是正则表达式的运用了,由此我们可以看出正则的重要性,它可运用在任何方方面面里,小的地方比如验证密码错误,数据输入格式是否错误,大的地方它可以用在对于各种数据的检测,比如我们题目集5的水文数据检测,对于输入数据的检测,是否合法。另外我们学习到了一些比较重要的东西,比如抽象类于接口的运用,接口的运用,它们能对于继承有何种方面的运用。这些都是在Java中相对来说比较重要的东西,经过这次题目集的运用,相信我们一定能在以后更加的熟练使用它们,且方便于我们进一步的学习~
浙公网安备 33010602011771号