oo第一次博客作业

一、前言

  这是我们OO课的第一次作业总结,学习java也将近一个月了,从上学期的C语言转变到现在的java,既有交叉又有改变。从面向过程到面向对象的转折,需要一段时间去适应。教学方式的多元化,学习平台的多样化给我们一个很好地学习环境,但从一次次作业的完成和总结中,我们也能学到很多。下面就是我对于之前pta平台上老师布置的题目集的一些相关题目的总结与梳理。

二、作业总结

1.判断三角形类型(题目集01-7-8)

题目分析:

  该题的重点内容就是如何判断三角形的类型,以及判断输入的三边是否能构成三角形。检验的是java的基础语法知识。

对于此题我的第一想法就是使用几个嵌套的if语句分别对三边的合法性,是否存在直角,是否有两条边相等,再分别进一步判断是否为等边三角形或者等腰直角三角形;

  实现代码如下:

 if((a>=1&&a<=200)&&(b>=1&&b<=200)&&(c>=1&&c<=200))//判断三边是否合法
        {
             if(a+b>c&&a+c>b&&b+c>a)//判断是否能形成三角形
            {
                if(a*a+b*b-c*c<0.000001||a*a+c*c-b*b<0.000001||c*c+b*b-a*a<0.0000001)//判断是否为直角三角形
                {
                    if(a==b||a==c||c==b)//判断是否为等腰三角形
                    {
                        System.out.println("Isosceles right-angled triangle");//等腰直角三角形
                    }
                    else 
                        System.out.println("Right-angled triangle");//直角三角形
                }
                 else if(a==b||b==c||c==a)
                 {
                     if(a==b&&a==c)//判断是否为等边三角形
                         System.out.println("Equilateral triangle");//等边三角形
                     else
                         System.out.println("Isosceles triangle");//等腰三角形
                 }
                 else
                     System.out.println("General triangle");//普通三角形
             }
            else
                System.out.println("Not a triangle");//无法构成三角形
        }
       else 
           System.out.println("Wrong Format");//数据非法

 改进与解析:

  这样简单通俗易懂,一目了然,但却有一点冗长。思虑过后认为用switch语句更为清爽直接一些

其中有一点要提的是,一开始判断三条边是否成直角的时候判断条件写的是:

a*a+b*b-c*c==0||a*a+c*c-b*b==0||c*c+b*b-a*a==0
比较浮点数是否相等,比较特殊,最好不要用 ==,比如浮点数a和b进行比较,写成if(a ==b)有时也许会出现你不期望出现的情况。
这样损失了一部分精度,导致一些测试点无法通过。最好用比较,例如本题:
a*a+b*b-c*c<0.000001||a*a+c*c-b*b<0.000001||c*c+b*b-a*a<0.0000001

 

 下面是代码的复杂度分析

Metrics Details For File 'Main1.java'
--------------------------------------------------------------------------------------------

Parameter Value
========= =====
Project Directory D:\新建文件夹\Main1\src\
Project Name Main1
Checkpoint Name Baseline
File Name Main1.java
Lines 38
Statements 26
Percent Branch Statements 42.3
Method Call Statements 11
Percent Lines with Comments 0.0
Classes and Interfaces 1
Methods per Class 1.00
Average Statements per Method 23.00
Line Number of Most Complex Method 3
Name of Most Complex Method Main1.main()
Maximum Complexity 23
Line Number of Deepest Block 17
Maximum Block Depth 6
Average Block Depth 3.11
Average Complexity 23.00

--------------------------------------------------------------------------------------------
Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls

Main1.main() 23, 23, 6, 11

--------------------------------------------------------------------------------------------
Block Depth Statements

0 2
1 2
2 8
3 3
4 4
5 7
6 1
7 0
8 0
9+ 0
--------------------------------------------------------------------------------------------

  

2.求下一天(题目集02-7-4)

题目分析:

该题的重点是判断是否为闰年,判断输入日期是否合法,以及求输入日期的下一天,检验的是学会构造一些相关方法,以及方法的调用;

对于此题我的想法是按照题目的要求构造三个相关方法,分别用于判断闰年,判断日期是否合法以及求下一天的日期;

1)判断闰年,且返回布尔类型,判断闰年的条件已经很熟悉了,重点在于构造方法以及返回布尔值,但其实这都很简单,话不多说直接上代码:

public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型 
    {
        boolean isLeapYear = (year%4==0&&year%100!=0)||year%400==0;
            return isLeapYear;
    }

2)判断输入的日期是否合法,同样返回值也是布尔型,思考了一下,就按照判断闰年的方法试着仿写,并不难,同样上代码:

public static boolean checkInputValidity(int year,int month,int day)//判断输入日期是否合法,返回布尔值
    {
      
        boolean checkInputValidity = (year>=1820&&year<=2020&&month>0&&month<=12&&day<=s[month]&&day>0);
                return checkInputValidity;
    }

3)求输入日期的下一天,也是本题的重点,一开始的主要想法就是先判断数据是否合法,然后判断是否为闰年,然后用if语句分支写出各种情况下的年月日。也是比较简单的,但是一定得注意嵌套的时候的各种条件用,例如2月,12月,各个月的月末都是比较特殊的,应当注意。最后的惯例,上代码:

public static void nextDate(int year,int month,int day)  //求输入日期的下一天
    {
        int a=0,b=0,c=0;
        int s[]=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            s[2]=29;
        if(checkInputValidity(year,month,day))//判断日期是否合法
        {
            if(month==12)
        {
            if(day==s[month])//特殊日期12月月底
            {
                a=year+1;
                b=1;
                c=1;
            }
           if(day>0&&day<s[month])
            {
                a=year;
                b=month;
                c=day+1;
            }
        }
        if(month<12)
        {
            if(day==s[month])//各个月的月底
            {
                a=year;
                b=month+1;
                c=1;
            }
            if(day>0&&day<s[month])
            {
                a=year;
                b=month;
                c=day+1;
            }
        }
        System.out.println("Next date is:"+a+"-"+b+"-"+c);
        }
        else System.out.println("Wrong Format");
    }

4)最后是主函数,比较重要的是学会如何调用相关方法,emmmm,也没啥好说的,还是上代码吧:

 public static void main(String[] args)//主方法 
   {
       Scanner in = new Scanner(System.in);
int year =in.nextInt();
        int month =in.nextInt();
       int day =in.nextInt();
       yxy.nextDate(year,month,day);
   }

最后!在 main() 方法中只能直接调用静态方法,如果想调用非静态方法,需要将当前类实例化,然后通过类的对象来调用。就相当于前面代码中的

 Main yxy=new Main();

3.求前N天(题目集02-7-5)

题目分析:该题与前一题求下一天其实主要思想差别不大,只是在判断日期的时候应该多加注意,比较于上一道题,这一道的题判断更加繁琐,需要更加细心一些。

对于此题我的想法就是仿造上一题的写法,但在输入时候了解到另一种写法,能够有效的判断一部分输入值是否合法,在下面我也会提起并且稍微讲解一下。因为判断时候合法以及判断是否为闰年的方法与上一题基本一致,这一题就不再提了,重点讲一下求前N天的方法以及Main方法。

1)求前后N天,分为了n大于0,和n小于0的两种情况就可以求前N天和后N天。总体来说,比较简单,甚至比上一题的代码更加简洁。

 

public static void nextDate(int year,int month,int day,int n) {
        int[] mm={0,31,28,31,30,31,30,31,31,30,31,30,31};
        if (isLeapYear(year))mm[2]=29;
        day-=n;
        if (n>0){
            while (day<=0){
                month--;
                if (month==0){
                    month+=12;
                    year--;
                }
                day+=mm[month];
            }
        }else if (n<0){
            while (day>mm[month]) {
                day-=mm[month];
                month++;
                if (month==13){
                    month-=12;
                    year++;
                }
            }
        }
        System.out.println(n+“ days ago is:"+year+"-"+month+"-"+day);
    }

 2)主方法

 这里值得一讲的是使用了方法hasnextInt(),java中hasNextInt方法用来判断下一个输入是否是int型整数,函数原型为 public boolean hasNextInt(); 函数的返回类型是boolean,也就是说如果下一个输入可转换为整数,那就返回true,否则返回false。

public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        boolean x=true;
        int a=0,b=0,d=0,n=0;
        if (in.hasNextInt())
            a= in.nextInt();
        else
            x=false;
        if (in.hasNextInt())
            b= in.nextInt();
        else
            x=false;
        if (in.hasNextInt())
            d= in.nextInt();
        else
            x=false;
        if (in.hasNextInt())
            n= in.nextInt();
        else
            x=false;

        if (checkInputValidity(a,b,d,n)&&x){
            nextDate(a,b,d,n);
        }else
            System.out.println("Wrong Format");

    }

    public static boolean isLeapYear(int year) {
        boolean ret=false;
        if ((year%100!=0&&year%4==0)||(year%400==0)){
            ret=true;
        }
        return ret;
    }

 

 

4.定义日期类(题目集03-7-2)

题目分析:该题一上一题目集的7-4是一样的,不过这里要求定义一个日期类,需要自己定义一些方法,主要方法的构架如下图:

同时,该题还有一些要求要求,必须保证类的封装性
(1)year、month、day等属性必须是私有成员
(2)类中的方法,必须针对类的year、month和day进行操作,而不是简单的题目集2中的写法。

这在C语言当中就相当于定义一些函数,然后在主函数当中调用了,这样使得主方法比较简单明了,而且即用即调,更加利于代码的编写。这题的要求当中,创建了一些无参构造方法,以及getter及setter方法

封装数据,对私有属性进行封装,即只是暴露出public方法来访问。但是为什么要这么做呢?封装的作用就是保护,保护属性本身不被篡改。比如有些属性只是可读但不可写,那么只提供它的getter方法就好,意思就是某些属性只能单一方向的被访问,getter和setter就是提供这样的接口,对于public的属性,可以直接使用类名来访问,自身的“安全性”就降低了。

具体的代码如下:

private int year;//
     int month;//
    private int day;//
    private int id;//账号
    private double balance;//余额
    private double annuallnterestRate;//当前利率
    private  Date dateCreated;
    public Date(){//无参函数
    }
    public Date(int year,int month,int day)//获得年月日
    {
        this.year=year;
        this.month=month;
        this.day=day;
    }
    public int getYear()//输出年
    {
        return year;
    }
    public void setYear(int year)//输入年
    {
        this.year=year;
    }
    public int getMonth()//输出月
    {
        return month;
    }
    public void setMonth(int month)//输入月
    {
        this.month=month;
    }
    public int getDay()//输出日
    {
        return day; 
    }
    public void setDay(int day)//输入日
    {
        this.day=day;
    }

至于其他方法构造与上一题基本的想法一样,所以就不再附上代码了,也不再做解释了。

另外,对于getter和setter这两个方法查了一些资料,归纳如下:

 setter方法
1.可以限制和检验setter方法传入的参数
2.隐藏对象内部数据结构
3.保持对象在每个状态的完整性
getter方法
1.按照客户的期望返回格式化数据
2.控制服务的顺序(例如只有当连接建立时getter方法才返回相应实例)

 

5.一元多项式求导(类设计)(题目集03-7-3)

题目分析:这一题的难度对我来说很大,现在也没能搞定一些方法和思想的实现,看到这道题的时候,我整个人都是懵的,第一次看到这么长的题,经过我仔细分析和琢磨之后,主要的想法就是去空格,分割,匹配,求导,但看起来简单,实际实现起来比较困难。最好的方法就是使用正则表达式,但因为我才疏学浅,不能很好地应用,就按照老师9给的提示写了一段,但还是有所缺欠,这里就不放代码出来了,等完全写出来了之后再说吧。

对于去空格只需要用一个replace的方法将字符串里的空格替换为空就行。例如:

String thee=in.nextLine();
            String thee1=thee.replace(" ","");//删去所有空格

 

对于常量的想法是首先先排查该项中是否含有’x‘,如果不含则该项为零,当一整个多项式都为常数时输出0,如果仅为一项,则该项为null。

正则表达式是用一个字符串来验证一类字符串,查找字符串,替换等;不是很会,就讲一些我知道的。

Matches()当且仅当正则匹配整个字符串时,,split(),replaceFirst(),replaceALL()

Group()返回匹配结果

 

三、体会与想法

一开始以为java跟c语言应该差别不大,或者说学了C语言在学java应该会很简单,但没想到的是,java远比我想想中的难得多,也是因为学过C语言的缘故,java的进程很快,而且,一开始在写代码的时候,总是用写C语言的思想来写,以至于有时候忽略了很多细节,比如构造一个对象啊定义一个结构体啊什么的,再者,java语言与c语言在写法上有较大的改变,应该加紧习惯起来。一些方法啊什么的都需要我们通过多写一些实例题去发现去了解,比如这次的正则表达式。

System.out.println("一学java深似海"));

四、相关资料

1、Getter和Setter方法作用https://blog.csdn.net/Jason_LH1024/article/details/90900339

2、多项式 正则表达式参考http://www.bubuko.com/infodetail-2360245.html

3、sourcemonitor使用方法https://blog.csdn.net/qq_34400736/article/details/53464738

posted on 2021-04-04 15:31  木鱼余  阅读(148)  评论(0)    收藏  举报