第二次blog
Blog2
前言:
经过这三次的pta作业,我总结出这三次的重点有:
- 总体来说,这三次的pta题目难度较前三次的编程题的难度确实有所降低,但在正则表达式的题目的编写过程中确实让我们感受到了极大的困难,这是我们目前收到的较大的编写阻力。
 - 这三次的题目集的题目总量可能相对较多,但是其的总体难度的下降让我们可以接受,尤其是在题目集5和题目集6中,老师给我们添加了一些较为简单的题目进行练手,可以让我们更好的去熟悉编程,去养成编程习惯。
 - 在这次的题目集中,我了解到了继承与多态的运用,继承可以方便的将我们重复使用的一些限定条件进行方便的调用,也了解到了继承与多态的抽象概念,哈希表的运用还有Arrays及Collections的简单应用。
 
设计与分析:
1:题目集4(7-2)、题目集5(7-5)两种日期类聚合设计的优劣比较
题目集4(7-2)的类图:
 
这次题目给了我们类图,这将方便我们对于题目的编写,我们在这题要做的就是将上图这些类进行代码的编程实现然后完成主函数的编写,在主函数的编写过程中完成对代码中分类的调用及运算。我们可以通过类图观察到,聚合一的大部分类关系较为紧密,类的数量庞大可以将其看做是类与类之间的关系看做是类与类之间的组合。比如在聚合一中day,year,month三个类是同时共存的,可以说是这三个分类是同时工作的其中任一个出现问题都将导致其余两个类的工作,这三个类的对象会被同时生成并且同时调用。
题目集4(7-2)的圈复杂度:
 
通过上面的数据报表及其复杂度分析我们可以了解到,这次聚合一的题目的圈复杂度为11,可以看到这题的代码是较为简洁明了的,并不是过于的复杂。说简单单就是将闰年判断,月份判断,合法度判断的逻辑结构写的更叫明了就可以使代码变得较为简单,不会出现太高的复杂度。但这一题的代码间耦合度较高,所以一但出现问题将会导致大量的代码像多米诺骨牌一样出现连锁反应,这是在代码编程过程中我们需要注意的,过高的耦合度并不符合面向对象的程序设计的要求。
源码:import java.util.Scanner;
public class Main {
public static void main(String[]args)
{
Scanner in=new Scanner(System.in);
int a=in.nextInt();
if(a<1&&a>3)
{
System.out.println("Wrong Format");
System.exit(0);
}
int j=in.nextInt();
int k=in.nextInt();
int l=in.nextInt();
Year year=new Year(j);
Month month=new Month(j,k);
Day day=new Day(j,k,l);
DateUtil dateUtil=new DateUtil(j,k,l);
if(j<1900||j>2050)
{
System.out.println("Wrong Format");
System.exit(0);
}
if(k>12||k<1)
{ System.out.println("Wrong Format");
System.exit(0);
}
else if(k==1||k==3||k==5||k==7||k==8||k==10||k==12)
{
if(l<=0||l>31)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
if(k==2)
{
if(year.isLeapYear(j))
{
if(l<=0||l>29)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
else
{
if(l<0||l>28)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
if(k==4||k==6||k==9||k==11)
{
if(l<=0||l>30)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
if(a==1)
{
int x=in.nextInt();
day.setMonth(month);
day.setYear(year);
month.setYear(year);
for(int i=0;i<x;i++)
{
day.dayIncrement();
}
int y=year.getValue();
int m=month.getValue();
int d=day.getValue();
System.out.println(y+"-"+m+"-"+d);
}
if(a==2)
{
int x=in.nextInt();
day.setMonth(month);
day.setYear(year);
month.setYear(year);
for(int i=0;i<x;i++)
{
day.dayReduction();
}
int y=year.getValue();
int m=month.getValue();
int d=day.getValue();
System.out.println(y+"-"+m+"-"+d);
}
if(a==3)
{
int b=in.nextInt();
int n=in.nextInt();
int m=in.nextInt();
DateUtil dateUtil2=new DateUtil(b,n,m);
day.setMonth(month);
day.setYear(year);
month.setYear(year);
if(b<1900||b>2050)
{
System.out.println("Wrong Format");
System.exit(0);
}
if(n>12||n<1)
{ System.out.println("Wrong Format");
System.exit(0);
}
else if(n==1||n==3||n==5||n==7||n==8||n==10||n==12)
{
if(m<=0||m>31)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
if(n==2)
{
if(year.isLeapYear(j))
{
if(m<=0||m>29)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
else
{
if(m<0||m>28)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
if(n==4||n==6||n==9||n==11)
{
if(m<=0||m>30)
{
System.out.println("Wrong Format");
System.exit(0);
}
}
if(year.getValue()>dateUtil2.getyear())
{
int i;
for( i=0;;i++)
{
day.dayReduction();
if(year.getValue()==dateUtil2.getyear()&&month.getValue()==dateUtil2.getmonth()&&day.getValue()==dateUtil2.getday())
{
break;
}
}
System.out.println(i+1);
}
else if(year.getValue()<dateUtil2.getyear())
{
int i;
for( i=0;i<100000;i++)
{
day.dayIncrement();
if(year.getValue()==dateUtil2.getyear()&&month.getValue()==dateUtil2.getmonth()&&day.getValue()==dateUtil2.getday())
{
break;
}
}
System.out.println(i+1);
}
else
{
if(month.getValue()>dateUtil2.getmonth())
{
int i;
for( i=0;;i++)
{
day.dayReduction();
if(year.getValue()==dateUtil2.getyear()&&month.getValue()==dateUtil2.getmonth()&&day.getValue()==dateUtil2.getday())
{
break;
}
}
System.out.println(i+1);
}
else if(month.getValue()<dateUtil2.getmonth())
{
int i;
for( i=0;i<100000;i++)
{
day.dayIncrement();
if(year.getValue()==dateUtil2.getyear()&&month.getValue()==dateUtil2.getmonth()&&day.getValue()==dateUtil2.getday())
{
break;
}
}
System.out.println(i+1);
}
else
{
if(day.getValue()>dateUtil2.getday())
{
int i;
for( i=0;;i++)
{
day.dayReduction();
if(year.getValue()==dateUtil2.getyear()&&month.getValue()==dateUtil2.getmonth()&&day.getValue()==dateUtil2.getday())
{
break;
}
}
System.out.println(i+1);
}
else if(day.getValue()<dateUtil2.getday())
{
int i;
for( i=0;i<100000;i++)
{
day.dayIncrement();
if(year.getValue()==dateUtil2.getyear()&&month.getValue()==dateUtil2.getmonth()&&day.getValue()==dateUtil2.getday())
{
break;
}
}
System.out.println(i+1);
}
else
System.out.println("0");
}
}
}
}
}
class Shape{
public Shape() {
System.out.println("Constructing Shape");
}
public double getArea() {
return 0.0;
}
}
class Circle extends Shape{
private double radius;
void setRadius(double radius) {
this.radius = radius;
}
public double getRadius() {//
return radius;
}
public Circle() {
super();
System.out.println("Constructing Circle");
}
public double getArea() {
return radius*radius*Math.PI;
}
}
class Rectangle extends Shape{
private double width;
private double length;
void setWidth(double width) {//
this.width = width;
}
void setLength(double length) {//
this.length = length;
}
double getWidth() {//
return width;
}
double getLength() {//
return length;
}
public Rectangle() {
super();
System.out.println("Constructing Rectangle");
}
public double getArea() {
return width*length;
}
}
class Ball extends Circle{
private double radius;
public double getRadius() {
return radius;
}
void setRadius(double radius) {
this.radius = radius;
}
public Ball() {
super();
System.out.println("Constructing Ball");
}
public double getArea() {
return Math.PI*4*radius*radius;
}
public double getVolume() {
return 4*Math.PI*radius*radius*radius/3;
}
}
class Year{
private int value;
Year()
{
}
Year(int value)
{
this.value=value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isLeapYear(int value) {
if((value%100!=0&&value%4==0)||value%400==0) {
return true;
}
else
{
return false;
}
}
public void yearIncrement()
{
value=value+1;
}
public void yearReduction()
{
value=value-1;
}
public boolean validate(int value)
{
if(value<1900||value>2050)
return true;
else
return false;
}
}
class Month{
private int value;
private Year year=new Year();
private int Year;
Month(){
}
Month(int yearValue,int monthValue){
Year=yearValue;
value=monthValue;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Year getYear() {
return year;
}
public void setYear(Year year) {
this.year = year;
}
public void resetMin()
{
value=1;
}
public void resetMax()
{
value=12;
}
public boolean validate(int value) {
if(value>12||value<1)
{
return true;
}
else
return false;
}
public void monthIncrement()
{
if(value==12)
{
resetMin();
year.yearIncrement();
}
else
{
value=value+1;
}
}
public void monthReduction()
{
if(value==1){
resetMax();
year.yearReduction();
}
else
value=value-1;
}
}
class Day{
private int value;
private Month month=new Month();
private Year year=new Year();
int Year;
int Month;
int[] mon_maxnum= {31,29,31,30,31,30,31,31,30,31,30,31};
int[] mon_minnum= {31,28,31,30,31,30,31,31,30,31,30,31};
Day(){
}
Day(int yearValue,int monthValue,int dayValue)
{
Year=yearValue;
Month=monthValue;
value=dayValue;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Month getMonth() {
return month;
}
public void setMonth(Month month) {
this.month = month;
}
public void resetMin()
{
value=1;
}
public void resetMax()
{
if(year.isLeapYear(year.getValue()))
value= mon_maxnum[month.getValue()-1];
else
value= mon_minnum[month.getValue()-1];
}
public Year getYear() {
return year;
}
public void setYear(Year year) {
this.year = year;
}
public boolean validate(int value)
{
if(Month==1||Month==3||Month==5||Month==7||Month==8||Month==10||Month==12)
{
if(value<1||value>31)
return true;
else
return false;
}
else if (Month==4||Month==6||Month==9||Month==11)
{
if(value<1||value>30)
return true;
else
return false;
}
else
{
if(year.isLeapYear(Year))
{
if(value>29||value<1)
{
return true;
}
else
{
return false;
}
}
else
{
if(value>28||value<1)
{
return true;
}
else
{
return false;
}
}
}
}
public void dayIncrement()
{
if(year.isLeapYear(year.getValue()))
{
if(value==mon_maxnum[month.getValue()-1])
{
resetMin();
month.monthIncrement();
}
else
value=value+1;
}
else
{
if(value==mon_minnum[month.getValue()-1])
{
resetMin();
month.monthIncrement();
}
else
value=value+1;
}
}
public void dayReduction()
{
if(value==1)
{
month.monthReduction();
resetMax();
}
else
value=value-1;
}
}
class DateUtil{
private Day day=new Day();
private Month month=new Month();
private Year year=new Year();
private int Day;
private int Year;
private int Month;
DateUtil(int y,int m,int d)
{
Day=d;
Month=m;
Year=y;
}
public Day getDay() {
return day;
}
public void setDay(Day day) {
this.day = day;
}
public Month getMonth() {
return month;
}
public void setMonth(Month month) {
this.month = month;
}
public Year getYear() {
return year;
}
public void setYear(Year year) {
this.year = year;
}
public int getyear()
{
return Year;
}
public int getmonth()
{
return Month;
}
public int getday()
{
return Day;
}
public boolean checkInputValidity()
{
if(day.validate(Day)||month.validate(Month)||year.validate(Year))
{
return true;
}
else
return false;
}
}
题目集5(7-5)的类图:
 
这题同样也是时间聚合类的题型,但我们可以明显看出这次的类与类之间的关系不再是环环相扣了,更像是一种平行的同步运行关系。这次的三个时间分类较比于聚合一更加的独立,这三个的时间分类的关系可以称作是关联,因此分类之间的耦合度较低,较比于聚合一来说更加方便的进行维护。
题目集5(7-5)的圈复杂度:
 
可以通过上图我们可以明显看出,这次的圈复杂度明显高于第一次,因为我们将三个时间类分开了,保证了三个分类独立运行的能力,所以复杂度会适当的上升,但是其降低了分类之间的耦合度,因此不会导致一个代码出错全部代码崩盘的糟糕情况。
2:题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
题目集4(7-3)的类图:
 
题目集6(7-5)的类图:
 
题目集6(7-6)的类图:
 
通过题目及类图我们可以明显看出,这三种图形设计均来自继承父类或者完成对接口的调用。在编写过程中,由于运用到了继承和接口,将会使我们的代码编写变得更加方便。我们可以通过对shape类的调用从而减少代码的编写量,大大减少了我们在编写代码时所花的时间。用简单点的话来说,所谓多态其实就是我们的编写对象在不同情况下对于编译器的不同执行表现。这将具体体现在定义和功能两个方面。
3.对三次题目集中用到的正则表达式技术的分析总结:
我们总体学习正则表达式的时间里已经不算短了,那么通过这么长时间的学习,我们可以得出这样的结论,在解决一些较长并且要求较多的正则表达式时,并不建议直接上手去做,更好的想法应该是去将他们进行分块化解决。正则表达式在我眼里看来可以说是java里中比较难的地方。我们每个人都知道,正则表达式是对代码进行纠正分析,如果要对一条数据包括许多项,则我们可以根据对应的特点(例如每个数据之间用哪种符号分割),这时候我们便可以通过split方法将其每项分隔开再分别进行操作,另外如果一条数据有许多项满足我们写的正则,这时候我们便需要用pattern和matcher创建对象,再用find方法找出每一项匹配的并用group方法进行分组再分别对每一组进行操作,另外我认为正则表达式中很重要的一点就是括号的使用,要合理地运用括号对正则表达式进行分组,这样才能匹配到正确的表达式,另外“\”符号也是非常重要的,因为正则表达式中许多符号都有两个意思,所以如果想正确地使用,我们必须写两个转义符。
踩坑心得:
 
这些都是我在编码过程中所犯下的错误痕迹,对于继承和封装的不熟练运用让我在编码过程中多了不少麻烦,类似于测试点中小数点的问题我时常缺漏,经常会导致测试中的无效边界测试点过不了,虽然我对类的使用还是不熟练,但我体会到了Java类中的方便之处。
总结:通过这三次的题目集,我学到了对于复杂问题的类的设计,以及对于每个类当中具体的构造方法的设计,对于正则表达式的世纪应用,这类的知识对于我们以后进行带有实际生活背景的问题的程序的编写有很大的帮助,比如之后在java课程设计当中,如果我们要做一个系统,需要实现用户的注册和登录,在用户输入注册是=时,密码之后,我们需要使用正则表达式判断用户填写的新密码是否符合我们的格式要求。对于抽象类,抽象方法,父类与子类的继承关系,接口的实现等知识点更是让我受益匪浅,对于一些特定的程序,这些知识可以在以后我们面对它们时对其进行简化,提高效率,减少工作量。对于这些继承和接口方面的知识,我觉得我需要更进一步的学习与巩固,以便于以后更好更灵活的使用它们。
                    
                
                
            
        
浙公网安备 33010602011771号