前言:这三次实验还是很有意义的,也算是让我从单纯的C思考方式中有了一点JAVA的思维方式,能够感觉到一些面向过程和面向对象的不同之处,总体对于我个人来讲可能是收获比较大吧,虽然说是一个小方面。

题目集一:

主要知识点就是熟悉Scanner类 import java.util.Scanner;  第一次PTA总共题量适中,8道题,题比较简单,是一个让我们认识JAVA的简单过程,学会如何来创建、编译以及执行JAVA程序,题目很基础

题目集二

主要知识点我觉得就是加深对Scanner类应用的理解,以及Java中数组的使用,和一些少量的面向对象的理解应用,整体难度我个人认为比较适中,对于刚入手的新手来说有难有易,题量不多,关键在于思路的构建以及理解。

题目集三:

从题目集三开始,对于面向对象的理解应用就开始有很大的拓展了,题量不多,但难度对于我而言可能很有难度。

设计与分析:

1、题目集一 7-8 判断三角形的类型PTA 前三次作业总结_面向对象

 

 

要求是由键盘输入三条边,来判断什么类型的三角形,或者能不能构成三角形。PTA第一次作业,对于面向对象的理解很淡,此题我是运用对于C的理解来进行编码的。 ,整体一个Main方法构成,通过数学三角形边与边之间的关系,首先来判断它能不能构成三角形,也就是排除非法输入,以及三条边条件不能构成三角形。(中间内容已省略,下面解析会展出)

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
            Scanner input = new Scanner(System.in);
            double x,y,z;
            x = input.nextDouble();
            y = input.nextDouble();
            z = input.nextDouble();
            if((x >= 1 && x <= 200)&&(y >= 1 && y <= 200)&&(z >= 1 && z<= 200)) {
                if(x+y>z&&x+z>y&&y+z>x) {
                    
                }
                else
                    System.out.print("Not a triangle");
            }
            else
                System.out.print("Wrong Format");
    }
}

然后根据题目要求,已经符合三角形的数据,进行判断类别:等边三角形,则输出“Equilateral triangle”、等腰直角三角形,则输出“Isosceles right-angled triangle”、等腰三角形,则输出“Isosceles triangle”、直角三角形,则输出“Right-angled triangle”、一般三角形,则输出“General triangle”,代码如下:(注:在满足上面条件下)

                     if(x==y||x==z||y==z) {
                        if(x==y&&x==z) {
                            System.out.print("Equilateral triangle");
                        }
                        else if(x==y&&x*x+y*y-z*z<0.00001) {
                            System.out.print("Isosceles right-angled triangle");
                        }
                        else if(x==z&&x*x+z*z-y*y<0.00001) {
                            System.out.print("Isosceles right-angled triangle");
                        }
                        else if(y==z&&z*z+y*y-x*x<0.00001) {
                            System.out.print("Isosceles right-angled triangle");
                        }
                        else 
                            System.out.print("Isosceles triangle");
                    }
                    else if(x*x+z*z==y*y||z*z+y*y==x*x||x*x+y*y==z*z) {
                        System.out.print("Right-angled triangle");
                    }
                    else
                        System.out.print("General triangle");

就这道题来说,难度不大,C方面的思考是完全可以的,但是有一个坑的地方在于两边之和减第三边要小于0.00001,刚开始做这道题的时候没注意,测试点一直过不去,通过询问同学了解原因,解决这个问题。而且要注意,由于每一个if条件里要素过多,写的时候要分的清楚,否则可能会缺很多东西,改起来也比较麻烦。

2、题目集一 7-4 求下一天

PTA 前三次作业总结_封装_02

 

要求从键盘输入年月日,然后系统给出所输入日期的下一天。在这里就强调了必须有几个方法,而不是一个Main写到底,类比于C,各个方法可以看成各个函数,最终都在main方法中进行引用,这里面新出现了一个“boolean”,布尔类型,通过它的返回值为 true 或 false 借助布尔类型,我们可以来进行判断输入的年是否为闰年,输入的年月日是否符合我们所给出的预期标准,也就是是否合法,题目中给年份规定了所取范围。(由于闰年与平年日期是不同的,所以进行判断之后在月份中我决定创建2个整数数组,如果闰年就用moun2,如果平年就用moun。)(判断闰年方法,年份被4整除或者年份不能整除100的同时可以整除400)

    public static boolean isLeapYear(int year) {
        boolean leapyear =  (year % 4 ==0&&year % 100 !=0)||year % 400 == 0;
        return leapyear;
    }//判断year是否为闰年,返回boolean类型 
    public static boolean checkInputValidity(int year,int month,int day){
        int []moun={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int []moun2= {0,31,29,31,30,31,30,31,31,30,31,30,31};
        boolean check;
        if(!isLeapYear(year)){
            check = (year>=1820&&year<=2020&&month>0&&month<=12&&day>0&&day<=moun[month]);
        }
        else
            check = (year>=1820&&year<=2020&&month>0&&month<=12&&day>0&&day<=moun2[month]);
        return check;
    }//判断输入日期是否合法,返回布尔值

本题的重点就在于下一天的判断,当符合了系统给定的要求之后,计算下一天,这时候就有多种情况,如果是12月的最后一天,那不仅日要改变,月、年一样都要改变;如果是其中一个月的最后一天,日要改变,月也要改变,而且闰年与平年的情况也不同,要优先判断,所以在 void nextDate(int year,int month,int day) 这个方法中,我们就应用了上述两种布尔类型判断方法。

public static void nextDate(int year,int month,int day) {
        int []mount={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int []mount2= {0,31,29,31,30,31,30,31,31,30,31,30,31};
        if(checkInputValidity(year,month,day)) {
            if(!isLeapYear(year)) {
                if(month==12) {
                    if(day==31) {
                        year = year + 1;
                        month = 1;
                        day = 1;
                    }
                    else {
                        day = day+1;
                    }
                }
                else{
                    if(day==mount[month]) {
                    month=month + 1;
                    day = 1;
                }
                else
                    day=day + 1;
                }
            }
            else {
                if(month==12) {
                    if(day==31) {
                        year = year + 1;
                        month = 1;
                        day = 1;
                    }
                    else {
                        day = day+1;
                    }
                }
                else{
                    if(day==mount2[month]) {
                    month=month + 1;
                    day = 1;
                }
                else
                    day=day + 1;
                }
            }
            System.out.print("Next date is:"+year+'-'+month+'-'+day);
        }
        else System.out.print("Wrong Format");
    }//求输入日期的下一天

最后,也是最简单的,就是写main方法了,这里我才用了数组输入,也可以不用这样,增加圈复杂度,应该进行改进,直接输入就好了,然后在把输入项带到下一天的方法中,程序要求实现

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int []arr = new int[3];
        for(int i=0;i<3;i++) {
            arr[i] = input.nextInt();
        }
        nextDate(arr[0],arr[1],arr[2]);
    }//主方法 

作为第二次作业,已经不像第一次那样,直接C的方法全部解决,有了一丝丝面向对象的那种感觉,虽然说感觉不深,然后学习了布尔类型,有一个坑的地方在于一开始没理解boolean类型,饶了很多圈子,之后查阅书籍,了解到返回true和false,然后对这种方法加以运用,还有就是对于各个条件点的分析,我一开始做的时候并没有考虑到如果12月最后一天,整体要进行改变,导致出现了乌龙的情况,出现了12月32日,判断是否合法时,也就是public static boolean checkInputValidity(int year,int month,int day)这个方法中,一开始并没有想到平润区别,只是在考虑输入日期是否合法,是否满足题目所给“出的年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31]”这个条件,而忘了去判断是否是闰年,细节方面还是有欠缺,还是需要多加练习才能养成多思考的意识。否则就会像我这样PTA 前三次作业总结_取值范围_03

 

 3、题目集三 7-2 定义日期类

PTA 前三次作业总结_java_04

 

 从这次作业开始,就很有JAVA的感觉了,每一个方法都很具体,而且不是一个类了,本题中要求是自定义一个DATE类,并且首次出现了私有属性,这四个字,这个私有属性就是一个小小的坑,在JAVA中定义private可以进行封装,将属性和方法用private进行封装,想要访问被封装的属性就要提供getter与setter,在写这道题的时候,并没有想那么多,直接开做,就导致不知道这个要求,然后就出现了错误(如下图)。PTA 前三次作业总结_面向对象_05

 

 在这里,简单说一下setter方法和getter方法。setter方法:主要就是进行属性内容的设定和修改。getter方法:就是进行属性内容的获取,在这里以定义私有属性年份为例:

                              private int year;
                              public int getYear() {
                            return year;
                          }
                          public void setYear(int year) {
                            this.year = year;
                          }

由于main类很简单,就是进行输入,以及对Date类中方法的引用,所以我们先来看Date类。

和上一题很像,要求我们自定义Date类然后算出下一天,按照表中所给出的方法进行定义,每个属性的类型给的也很清晰,年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31],然后按照所给图示,对Date类进行构建。

首先就是对私有属性进行封装定义,每一个属性按照类型进行初始化定义,在JAVA中,如何你定义了私有属性,在你建立的私有属性的左侧序号列中就会出现黄色的小气包,点击它,里面直接有“create getter and setter for '你所定义的私有属性' ”然后系统就可以直接帮助你完成setter方法和getter方法的建立,与Dev-C相比,JAVA真的很方便,私有属性建立代码如下:

private int year;
    private int month;
    private int day;
    int []mon_maxnum = new int[] {0,31,28,31,30,31,30,31,31,30,31,30,31};
    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;
    }

然后是布尔类型方法的建立,来判断是否为闰年或平年,以及所输入的日期是否符合给定的输入标准。

public static boolean isLeapYear(int year) {
        boolean leapyear =  (year % 4 ==0&&year % 100 !=0)||year % 400 == 0;
        return leapyear;
    }//判断year是否为闰年,返回boolean类型 
    public static boolean checkInputValidity(int year,int month,int day){
        int []moun={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int []moun2= {0,31,29,31,30,31,30,31,31,30,31,30,31};
        boolean check;
        if(!isLeapYear(year)){
            check = (year>=1900&&year<=2000&&month>0&&month<=12&&day>0&&day<=moun[month]);
        }
        else
            check = (year>=1900&&year<=2000&&month>0&&month<=12&&day>0&&day<=moun2[month]);
        return check;
    }//判断输入日期是否合法,返回布尔值

然后就是获取下一天,和之前一样,坑点就是一年的最后一天,闰年多一天,以及各个月份的最后一天,在这个方法中我们也是引用了之前所示的俩个Boolean类型判断方法,来进行平年还是闰年的区分,以及判断输入的日期是否正确,进判定之后通过各类条件判断,最后进行系统输出,给出答案。

public static void getNextDate(int year,int month,int day) {
        int []mount={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int []mount2= {0,31,29,31,30,31,30,31,31,30,31,30,31};
        if(checkInputValidity(year,month,day)) {
            if(!isLeapYear(year)) {
                if(month==12) {
                    if(day==31) {
                        year = year + 1;
                        month = 1;
                        day = 1;
                    }
                    else {
                        day = day+1;
                    }
                }
                else{
                    if(day==mount[month]) {
                    month=month + 1;
                    day = 1;
                }
                else
                    day=day + 1;
                }
            }
            else {
                if(month==12) {
                    if(day==31) {
                        year = year + 1;
                        month = 1;
                        day = 1;
                    }
                    else {
                        day = day+1;
                    }
                }
                else{
                    if(day==mount2[month]) {
                    month=month + 1;
                    day = 1;
                }
                else
                    day=day + 1;
                }
            }
            System.out.println("Next day is:"+year+'-'+month+'-'+day);
        }
        else System.out.print("Date Format is Wrong");
    }//求输入日期的下一天

最后又是最简单,最愉快的main类,通过Scanner类,达到键盘输入的效果,定义x为Date类,然后对X的各项属性进行键盘输入,最后把x带入到下一天“public static void getNextDate(int year,int month,int day)”方法中,实现整个系统。

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        Date x = new Date();
        x.setYear(input.nextInt());
        x.setMonth(input.nextInt());
        x.setDay(input.nextInt());
        Date.getNextDate(x.getYear(), x.getMonth(), x.getDay());
        
    }//主方法 
}

这道题其实和第二题特别像,除了第三题进行了对私有属性的定义,对方法和属性进行了封装,使整体越来越具体,面向对象的意味进一步加深,有了第二题的经历,所以做这一道题的时候,并没有特别困难,反而上手的十分迅速,对私有属性封装进行一下了解,这道程序题就可以轻松解决了。

4、题目集三 7-3 一元多项式求导

PTA 前三次作业总结_私有属性_06

 

 这道题我个人觉得很有难度,没有完全做出来,只作出来了一部分,题目是在一行中输入一个等待计算的导函数的表达式,不符合要求导函数的地方有很多,在这里我判断了所给式子指数为0、系数为0和为常量的情况。常量判断很简单,如果输入字符中有x则让temp记为1(初始temp = 0),然后进行判断,如果temp = 0,则系统输出0,因为都是常量,导函数为0,代码如下:

public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s1 = input.nextLine();
        s1=s1.replaceAll(" ", "");
        int i = 0;
        int n = s1.length();
        int temp = 0;
while(i<n){
                ......
                if(s1.charAt(i)=='x') {
                
                temp = 1;
                arr[p] = i;
                p++;
            }
                i++;
}
 if(temp==0) {
            System.out.print("0");
        }

指数和系数为0,当输入的字符中第i项为0,判断i前面也就是i-1,如果i前面是‘+’或者‘-’或者‘*’或者‘^’,这种情况都是不成立的也就是指数或系数为0,排除这些情况。

if(s1.charAt(i)=='0') {
                if(s1.charAt(i-1)=='+'||s1.charAt(i-1)=='-'||s1.charAt(i-1)=='*'||s1.charAt(i-1)=='^'){
                    System.out.print("Wrong Format");
                    return ; 
                }
                if((s1.charAt(i-1)=='+'||s1.charAt(i-1)=='-'||s1.charAt(i-1)=='*')&&s1.charAt(i+1)=='^') {
                    System.out.print("Wrong Format");
                    return ;
                }
                if((s1.charAt(i-1)=='+'||s1.charAt(i-1)=='-'||s1.charAt(i-1)=='*')&&s1.charAt(i+1)=='*'){
                    System.out.print("Wrong Format");
                    return ;
                }
                if(i==0) {
                    System.out.print("Wrong Format");
                    return ;
                }
                if(i==n&&(s1.charAt(i-1)=='+'||s1.charAt(i-1)=='-'||s1.charAt(i-1)=='*')) {
                    System.out.print("Wrong Fromat");
                    return ;
                }
            }

由于能力有限,并没有能接下去做出来。

踩坑心得:

在上面每一题的心得中,已经表明了,其实踩坑最多的就是各种情况露了或者是一些关于代码不理解的错误,我们使用的JAVA软件eclipse很好用,以前在c中一些简单语法错误,自己看半天都没有看出来,在JAVA中很方便,会直接提醒并且可以点击更改,还是体验很好的。

改进建议:

第二题读取数组,可以直接写对应的方法来读取,不需要数组进行读取,第四题,其实判别不需要那么多,系数与指数为0的情况可以用(代码如下)来判别

if(s1.charAt(i-1)=='+'||s1.charAt(i-1)=='-'||s1.charAt(i-1)=='*'||s1.charAt(i-1)=='^')

第一题的话,三个的边是否能构成三角形,可以写成一个方法来判别,而不是一个main到底,同理,判定每个三角形类型,也可以单独写一个方法来进行判别。可以使程序更加简单明了,降低圈复杂度。

总结:

通过对这三作业的练习,明白了什么是类,方法,属性,Java和C的区别和相似,一些java语句的应用,以及一些基础的类的引用,同时也了解到自身对于JAVA了解还是不够深刻把,学习得不够好,要抽空多看看一些大佬的代码,去进行学习,一些JAVA自身的类应用,以及一些知识了解不深刻,导致每次做题的时候很多时间都是在查资料,应该多练题,加深理解,感觉上课的效果还是很明显的,老师教的很好,很认真,上课给我们讲代码,能帮助我们理解起来更加透彻,课件与实验,线上与线下的结合十分融洽,体验很好,作业质量也是越来越好,虽说难度提高的有点快(大概率是我学的还是不太行),总之希望,在JAVA的道路上越走越好吧,希望之后的作业以及实验都能完美完成。