20201314-李洋的第一次Blog

一.前言:

  1. 前三次的题目集主要涉及的知识点有。

(1)对于java语言的了解与编写,简单的Java语法,例如if的判断等等。

(2)关于类的了解以及简单的运用。

(3)关于类的更深的层次的了解,例如单一变量原则和封装性等等。

二.设计与分析

题目集一 7-8

 

此代码要求判断是什么类型的三角形。

 

if(a+b<=c||b+c<=a||a+c<=b){

                System.out.println("Not a triangle");

                System.exit(0);}

此代码为当错误输出三角形三边时,输出非三角形。

if(a==b&&b==c){

                System.out.println("Equilateral triangle");

                System.exit(0);

                }

此代码为输入三边相等时,输出等边三角形。

if(a==b&&a*a+b*b-c*c<=0.000001){

                System.out.println("Isosceles right-angled triangle");

            System.exit(0);}

此代码为直角三角形,当我写到这步,如果没有写a*a+b*b-c*c<=0.000001而是a*a+b*b=c*c时代码会输出错误数据,经过查询了解到直角三角形状三边的平方和会有误差。

if(a==b&&b!=c||b==c&&c!=a||a==c&&a!=b){

                  System.out.println("Isosceles triangle");

               System.exit(0);}

此代码为等腰三角形。

if(a+b>c&&b-a<c&&a-b<c)

                  {System.out.println("General triangle");

                   System.exit(0);}

此代码为输入正常的三角形

小结:此次题目本身并不难,但是仅仅34行代码,我的复杂度竟然高达18

原因是我的代码出现了许多if嵌套的现象,本身因为过度依赖if语句,再此

方便我已经做出调整,接下来的代码会尽量少用if语句。

 

  1. 题目集27-4

 

此题目要求测出

输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 

代码如下

public static boolean isLeapYear(int a){

    if((a%4==0&&a%100!=0)||a%400==0){

        return true;

    }

    else{

        return false;

}

建立一个是否为闰年的方法。

public static boolean checkInputValidity(int a,int b,int c){

            if((a<1820||a>2020||b<1||b>12||c<1||c>31)||(isLeapYear(a)==false&&b==2&&c==29))

                return false;

            else

                return true;       

建立一个输入是否为合法输入的方法。

if(isLeapYear(a)==true&&(m==1||m==3||m==5||m==7||m==8||m==10||m==12)){

                if(d<31){

                    d++;

                    System.out.println("Next date is:"+a+"-"+m+"-"+d);}

                if(d==31&&m!=12){

                    m++;

                    d=1;

                    System.out.println("Next date is:"+a+"-"+m+"-"+d);

                    System.exit(0);}

                if(m==12&&d==31){

                    d=1;

                    m=1;

                    System.out.println("Next date is:"+y+"-"+m+"-"+d);}}

               if(m==4||m==6||m==9||m==11){

                   if(d<30){

                       d++;

                       System.out.println("Next date is:"+a+"-"+m+"-"+d);}

                   if(d==30){

                       d=1;

                       m=m+1;

                       System.out.println("Next date is:"+a+"-"+m+"-"+d);}}

分类 当输入的年份为闰年时,每一个月的详细情况,在细分类每一个月

30天还是31天。

if(isLeapYear(a)==false&&(m==1||m==3||m==5||m==7||m==8||m==10||m==12)){

                if(d<31){

                    d++;

                    System.out.println("Next date is:"+a+"-"+m+"-"+d);}

                if(d==31){

                    d=1;

                     m=m+1;

                     System.out.println("Next date is:"+a+"-"+m+"-"+d);}}

               if(isLeapYear(a)==true&&(m==2)){

                   if(d<29){

                       d++;

                       System.out.println("Next date is:"+a+"-"+m+"-"+d);}

                   if(d==29){

                       d=1;

                       m=m+1;

                       System.out.println("Next date is:"+a+"-"+m+"-"+d);}}

分类,如果输入年份为平年时,详细分类月份。

 if( isLeapYear(a)==false&&(m==2)){

                   if(d<28){

                       d++;

                       System.out.println("Next date is:"+a+"-"+m+"-"+d);}

                   if(d==28){

                        d=1;

                       m=m+1;

                       System.out.println("Next date is:"+a+"-"+m+"-"+d);

                           System.exit(0);}}}}

2月份单独拿出来。

 

小结:在自己写这道题时,考虑的情况较少,并且自己代码设计的比较复杂,

比如如果把2月份单独拿出来后,根本不需要分类平年还是闰年,如果将

这部分代码删除,我的圈复杂度将会大大降低。

 

题目集二的 7-5

 

题目如下

输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。

代码如下

 public static boolean isLeapYear(int a){

    if((a%4==0&&a%100!=0)||a%400==0){

        return true;

}

定义一个判断是否为闰年的方法

  public static boolean checkInputValidity(int a,int b,int c,int n){

            if((a<1820||a>2020||b<1||b>12||c<1||c>31)||(isLeapYear(a)==false&&b==2&&c==29)||n<-10||n>10)

                return false;

            else

                return true;       

        }

判断是否输入合法。

      if(n<0){

先分类

当输入为n天前时

if((b==1||b==3||b==5||b==7||b==8||b==10)){

                if(c+k<=31){

                    i=c+k;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                }

                if(c+k>31){

                    j=c+k-31;

                    b=b+1;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                }

            }

如果为闰月时,首先判断c+k<=31是否超出了月份的最大值

如果超出则跳到下一个月份,如果没有超过,则留到本月

当每一次执行完后,System.exit(0);

终止程序。

 if(b==4||b==6||b==9||b==11){

                   if(c+k<=30){

                    i=c+k;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                }

                   if(c+k>30){

                    j=c+k-30;

                    b=b+1;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

               }

               }

                   if(b==2&&(isLeapYear(a)==true)){

                       if(c+k<=29){

                    i=c+k;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                   }

                        if(c+k>29){

                    i=c+k-29;

                    b=b+1;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                   }

                   }

此代码为当每个月时30天时,具体思路与上面一一致

if(b==2&&(isLeapYear(a)==false)){

                           if(c+k<=28){

                               i=c+k;

                     System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                           }

                           if(c+k>28){

                               i=c+k-28;

                    b=b+1;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                           }

                       }

            if(b==12){

                if(c+k>31){

                    a=a+1;

                    b=1;

                    i=c+k-31;

                     System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                }

                if(c+k<=31){

                    i=c+k;

                    System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                    System.exit(0);

                    }

            }

        }

此代码为当2月份和12月份时,2月份比较特殊,因为它只有28天或者

29天,所以单独分析一下,12月份是因为它可能出现跨年的现象,所以

    所以要分析一下是否出现了跨年,如果出现了跨年现象,在关于年份的变量要加一。

if(n>=0) {

         if((h==1||h==3||h==5||h==7||h==8||h==10)) {

         if(c-n>=0) {

         i=c-n;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }

         if(c-n<0) {

         i=31+c-n;

         b=b-1;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }   

         }

         if((h==4||h==6||h==9||h==11)) {

         if(c-n>=0) {

         i=c-n;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }

         if(c-n<0) {

         i=30+c-n;

         b=b-1;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }      

         }

if(h==2&&(isLeapYear(a)==true)) {

         if(c-n>=0) {

         i=c-n;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }

         if(c-n<0) {

         i=29+c-n;

         b=b-1;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }     

         }

         if(h==2&&(isLeapYear(a)==false)) {

         if(c-n>=0) {

         i=c-n;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }

         if(c-n<0) {

         i=28+c-n;

         b=b-1;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                     System.exit(0);

         }    

         }

         if(b==1&&c-n<0) {

         a=a-1;

         i=31+c-n;

         b=12;

          System.out.print(n+" days ago is:"+a+"-"+b+"-"+i);

                 System.exit(0);

         }

        }

    }

此代码是分析一下前n天,前n天则与后n天思路大致相似,但是要考虑上个月的月份情况,比如如果上一个月份为31天时,或者30天时,则需要分别考虑,单独将上一个月为2月和一月份分析,2月份是因为,他的天数

与其他的月份不同,一月份是因为他可能出现跨到前一年的情况,所以要单独

分析一下。

 

错误分析:

(1)刚刚开始写代码时,整体思路没有很清晰,所以并没有出现分类前n

  和后n天的情况,所以测试数据时,经常会出现日期超过30天或31天的情况,

(2)输入合法性检测时,没有考虑到2月份的特殊性,所以测试时,经常会出现有关2月份的测试数据不通过,

(3)没有考虑到出现跨年的状况,所以关于12月份 和一月份的测试数据不会通过,

(4)没有考虑到7月份8月份连个两个月31天的特殊情况。

   小结:

   此题难度相比前1次的题目集难度有一些提升,主要时要考虑的情况太多,

经常会出现少考虑,漏考虑的情况,还有一些月份的特殊性容易忽略到,

对于我自己还是过度依赖与if语句以及if语句的嵌套,自我反省是,关于Java的思想缺乏。

 

习题集37-2

定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。

要求:Date类结构如下图所示:

 

 

代码如下:

class Date{

    private int year = 0;

    private int month = 0;

    private int day = 0;

定义一个关于日期的类。

public Date(){

        

    }

类中的无参构造方法。

public Date(int year,int month,int day){

        this.year = year;

        this.month = month;

        this.day = day;

    }

类中的有参构造方法。

public void setYear(int year){

        this.year = year;

    }

    public void setMonth(int month){

        this.month = month;

    }

    public void setDay(int day){

        this.day = day;

    }

关于yearmonthdaysetter的方法

public int getyear(){

        return year;

    }

    public int getMonth(){

        return month;

    }

    public int getDay(){

        return day;

    }

关于YearMonthDaygetter的方法。

public  boolean  isLeapYear(){

     if((year%4==0&&year%100!=0)||year%400==0){

            return true;

        }

        else{

            return false;

        }

    }

在类中定义一个判断闰年的的方法。

 public  boolean checkInputValidity(){

        if((year<1900||year>2000||month<1||month>12||day<1||day>31)||(isLeapYear()==false&&month==2&&day==29))

            return false;

        else

            return true;       

    }

在类中定义一个输入是否合法的方法。

public  void nextDate() {

        int d=day,m=month,y=year+1;

        if(isLeapYear()==true&&(m==1||m==3||m==5||m==7||m==8||m==10||m==12)){

            if(d<31){

                d++;

                System.out.println("Next day is:"+year+"-"+m+"-"+d);}

            if(d==31&&m!=12){

                m++;

                d=1;

                System.out.println("Next day is:"+year+"-"+m+"-"+d);

                System.exit(0);}

            if(m==12&&d==31){

                d=1;

                m=1;

                System.out.println("Next day is:"+y+"-"+m+"-"+d);}}

           if(m==4||m==6||m==9||m==11){

               if(d<30){

                   d++;

                   System.out.println("Next day is:"+year+"-"+m+"-"+d);}

               if(d==30){

                   d=1;

                   m=m+1;

                   System.out.println("Next day is:"+year+"-"+m+"-"+d);}}

        if(isLeapYear()==false&&(m==1||m==3||m==5||m==7||m==8||m==10)){

            if(d<31){

                d++;

                System.out.println("Next day is:"+year+"-"+m+"-"+d);}

            if(d==31){

                d=1;

                 m=m+1;

                 System.out.println("Next day is:"+year+"-"+m+"-"+d);}

        }

        if(isLeapYear()==false&&m==12){

            if(d<31){

                d++;

                System.out.println("Next day is:"+year+"-"+m+"-"+d);}

            if(d==31){

                d=1;

                 m=1;

                 System.out.println("Next day is:"+y+"-"+m+"-"+d);}

        }

           if(isLeapYear()==true&&(m==2)){

               if(d<29){

                   d++;

                   System.out.println("Next day is:"+year+"-"+m+"-"+d);}

               if(d==29){

                   d=1;

                   m=m+1;

                   System.out.println("Next day is:"+year+"-"+m+"-"+d);}}

           if( isLeapYear()==false&&(m==2)){

               if(d<28){

                   d++;

                   System.out.println("Next day is:"+year+"-"+m+"-"+d);}

               if(d==28){

                    d=1;

                   m=m+1;

                   System.out.println("Next day is:"+year+"-"+m+"-"+d);

                       System.exit(0);}

               }

           }

    }

在类中定义一个计算日期的方法,这个计算日期的方法与上一题的思路类似。

public class text5{

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

Date c = new Date();

        c.setYear(input.nextInt());

        c.setMonth(input.nextInt());

        c.setDay(input.nextInt());

定义一个主方法,在主方法中定义一个date类型的c 通过手动向计算机传入的数据来更改date类中的私有变量 YearMonth'Day

然后在类中YearMonthDay来进行运算。

       c.isLeapYear();

c.checkInputValidity();

然后通过date类型的c来访问date类中的isLeapYear函数和chexkInputValidity函数。

 

错误分析:

(1)这是第一次接触类的代码,由于对于类的运用不太熟悉,所以刚开始,

主类无法与date类取得联系,

(2)刚刚开始在Date类中没有定义关于YearMonthDaysetter函数,

   getter函数,所以导致我在主类中的函数无法更改类中的私有变量。

(3)没有将类中的私有变量设置为private类型。

(4)将关于日期的函数写到了主类中,破坏了类的定义和封装性,

(5)刚刚开始我在类中定义的函数是由参数的,破坏了类的封装性

(6)在主函数中没有定义一个关于Date类型 的c,所以在主函数中输入的变量,根本改变不了类中的私有变量。

小结:

对于类的了解不是很深,经常会破坏类的封装性,所以经常会在主函数中,

写本该属于类中的东西,导致我所定义的类没有意义,很难做到单一职责

经常会把所有的东西写在一起,很不擅长写类,总是想把所有的东西写到

主类中,还是c语言的固有思想导致。缺少面向对象的思想。

 

习题集37-3

编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。 OO作业3-3题目说明.pdf

输入格式:

在一行内输入一个待计算导函数的表达式,以回车符结束。

输出格式:

  1. 如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
  2. 如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
  • 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
  • 当输出结果第一项系数符号为“+”时,不输出“+”;
  • 当指数符号为“+”时,不输出“+”;
  • 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。

输出格式见输入输出示例。

 

代码如下

String s = input.nextLine();

 String b = ".*0\\*x.*";

 String c = ".*x\\^0.*";

        String bc=b+"|"+c;

 boolean isMatch = Pattern.matches(bc, s);

 if(isMatch==true) {

 System.out.println("Wrong Format");

 System.exit(0);

判断一下所输入的多项式中是否出现有系数为0或者指数为0

如果有这种情况则输出"Wrong Format"。

s.replace(" ","");

char []a = s.toCharArray();

for(int i = 0;i<s.length()-1;i++) {

if(a[i]=='^'&&a[i+1]=='-')

a[i+1] = '#';

}

将多项式中的空格字符去掉并且将此字符串放入一个字符数组中

并且将字符数组中的指数符号变成#

String d = "";

for(int i = 0;i<a.length;i++) {

d = d+a[i];

}

d=d.replace("-","+-");

String []l1 = d.split("\\+");

将系数的负号变为+-,以防止切割加号时将负号切掉。

for(String e:l1) {

            e=e.replace(" ","");

e = e.replace("#","-");

int start =e.indexOf("x");

int mid =e.indexOf("*");

int end =e.indexOf("^");

切割完成后将x * ^分别记录下来。

if(start!=-1&&end!=-1) {

if(mid!=-1) {

BigInteger l2=new BigInteger(e.substring(0,mid));

BigInteger l3=new BigInteger(e.substring(end+1,e.length()));

BigInteger xishu = l2.multiply(l3);

BigInteger zhishu = l3.subtract(new BigInteger(1+""));

if(zhishu.equals(new BigInteger(0+"")))

System.out.print(xishu);

else {

      if(xishu.equals(new BigInteger(1+"")))

      System.out.print("x^"+zhishu);

      else if(xishu.equals(new BigInteger(-1+"")))

      System.out.print("-x^"+zhishu);

      else {

       if(xishu.compareTo(new BigInteger(0+""))>0);

       if(flag==1)

       System.out.print("+");

       System.out.print(xishu+"*x^"+zhishu);

      }

}

lazy = 1;

if(flag==0)

flag=1;

}

else {

if(e.charAt(0)=='-'){

BigInteger l4 = new BigInteger(e.substring(end+1,e.length()));

BigInteger xishu = l4.multiply(new BigInteger(-1+""));

BigInteger zhishu = l4.subtract(new BigInteger(1+""));

if(zhishu.equals(new BigInteger(0+"")))

System.out.print(xishu);

else {

      if(xishu.equals(new BigInteger(1+"")))

      System.out.print("x^"+zhishu);

      else if(xishu.equals(new BigInteger(-1+"")))

      System.out.print("-x^"+zhishu);

      else {

       if(xishu.compareTo(new BigInteger(0+""))>0);

       if(flag==1)

       System.out.print("+");

       System.out.print("*x^"+zhishu);

}

                          

}

}

else {

 

BigInteger l4 = new BigInteger(e.substring(end+1,e.length()));

BigInteger xishu = l4.multiply(new BigInteger(1+""));

BigInteger zhishu = l4.subtract(new BigInteger(1+""));

if(zhishu.equals(new BigInteger(0+"")))

System.out.print(xishu);

else {

      if(xishu.equals(new BigInteger(1+"")))

      System.out.print("x^"+zhishu);

      else if(xishu.equals(new BigInteger(-1+"")))

      System.out.print("-x^"+zhishu);

      else {

       if(xishu.compareTo(new BigInteger(0+""))>0);

       if(flag==1)

       System.out.print("+");

       System.out.print("*x^"+zhishu);

}

}

 

}

lazy = 1;

if(flag==0)

flag=1;

}

}

else if(start!=-1) {

if(mid!=-1) {

BigInteger num = new BigInteger(e.substring(0,mid));

System.out.print(num);

}

else {

BigInteger num = null;

if(e.charAt(0)=='x')

num=new BigInteger("1");

else if(e.charAt(0)=='-')

num=new BigInteger("-1");

else

num = new BigInteger(e.substring(0,start));

System.out.print(num);

}

lazy=1;

if(flag==0)

flag=1;

}

else

System.out.print("");

}

if(lazy==0)

System.out.print(0);

}

对于数组中每一个变量进行分析,包括是否为常数,并且是否系数为1等情况,

分情况讨论,讨论之后时求导的运算,然后输出。

 

错误分析:

(1) 对于多项式求导中的处理字符串方面了解不是很足,所以对于字符串方面的 刚开始写代码时 不了解如何切割字符串,所以在多项式求导中的每一项的拆分卡了好久,

(2) 对于关于字符串中的正则表达式了解很是不足,

(3) 在多项式求导中 起初没有将系数的负号考虑到,所以当我切割多项式的每一项时,出现了有两项在一起的情况。

(4) 没有对字符串中的空格的处理,所以当输出时出现了错误

(5) 在输出多项式时 我只想将每一项分别输出,却忽略了第一项的负号

所以在输出是第一项前面总是有一个负号。

 

小结:

本题对于多项式求导方面本身并不难,主要是考对于字符串处理方面,

对于我来说,关于字符串处理方面的知识储备不是很多,所以完成本题

对于我来说还是比较困难,虽然没有拿到满分,但是经过这道题后

我对于处理字符串方面了解了更多。

 

三.改进建议:

  1. 首先时圈复杂度方面,因为我过度依赖与if语句以及for语句,所以每一道题的复杂度都时特别特别高,老师说要控制在10以内,而我自己的代码复杂度要高出10的好几倍

可见就在代码的构造方面我的不足还是很大,在以后的题目集中,我会尽量少使用if语句

For语句,或者嵌套,是我的代码复杂度大大降低。

  1. 在构建代码思路方面,题目集的每一道题,我可能都会卡很长时间,我对于Java的思想

了解的不是很充分,在代码的构建方面也不是很擅长,经常会缺少情况,或者少考虑到一种或者多种情况。

  1. 经常想的不实际,我在写代码时很难找到正确的思路,经常会出现一种奇怪的思路,

对于Java编程思想很是欠缺

  1. 在面向对象方面,对于我来说有一个最大的难关就是,类的使用,经常会违背单一职责

或者来说 不知道如何分类,不知道代码中要写几个类,以及类的运用不是很熟练,

比如分类与主类之间的联系,经常会破坏类的封装性,经常创建了类,但是不知道如何使用

经常没有用到,而是所有的运算都在主类中完成的。

  1. 在类型转化时,我经常会将两个不一样类型的变量会进行运算。

 

四.总结:

在经过了一月的Java学习中和三次题目集,我大致知道了哪里的不足,可以针对这些不足来进行针对性的学习,了解了面向对象和c语言的区别,类,大致了解了对于类的使用

和类的定义 以及类的封装性等等,虽然不足之处有很多,但是经过这次题目集之后,这些不足之处也暴露出来很多。对于我以后的Java学习将会更加有益。

 

posted @ 2021-04-03 14:49  20201314-李洋  阅读(94)  评论(0)    收藏  举报