第一次博客作业

前言:

对于首次用Java来编程的我来说,在这三次作业中,首先了解到了一个完整的Java程序的构造。Java程序是以一个或者多个类组合而成,其中public class *****{}是Java程序的主体框架,代码都包含在这个框架内,class的含义是类,后面的是类名,整个类的所有代码都是在{}中定义完成的;而Java程序的作用体现在方法中,方法是语句的集合,用于执行某个功能,就像是main方法,它是程序执行的入口;我还充分了解了Java的基本语句,像定义变量,输入输出,赋值等等;对于某些具体运用的语句,像if else,while,switch等等的运用基本与c语言一致。在第三次作业里我了解到了无参构造方法与有参构造方法的差别及各自的使用,以及正则表达式的使用,这是我第一次接触正则表达式,在正则表达式的使用上还是不太熟练;还学会了类的创建与使用,在主类中创建新的类。这三次作业,前两次祖业的难度相对来说是较低的,但第一次的题量较多,第二次比较合适,第三次作业题量较少,但难度较高,特别是第三题。

设计和分析:

在这三次作业中,第一次作业较为简单,解题是用面向过程的思路来完成的,并没有遇到什么困难的地方,

题7-8

输入三角形三条边,判断该三角形为什么类型的三角形。

输入格式:

在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。

输出格式:

(1)如果输入数据非法,则输出“Wrong Format”; (2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”; (3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”; (3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”; (5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”; (6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”; (7)如果输入数据合法且能够成一般三角形,则输出“General triangle”

解题过程中遇到了一些细节问题。题7-8中,由于要判断三角形的类型,我们只能根据三角形三条边长度的关系来判断,通过比较三条边的关系就可以得出很多种情况,再通过if else语句来进行判断,所以运用了较多的if else语句,导致圈复杂度比较高。且在判断是否为等腰直角三角形的过程中由于直角边的平方相加后再开根得到的是无理数,这样就无法与斜边相等,于是编写a*a+b*b-c*c<0.000001来判断是否为等腰直角三角形。

 

   if((a<1||a>200)||(b<1||b>200)||(c<1||c>200))
            System.out.println("Wrong Format");
         else if((a+b)<=c||(a+c)<=b||(b+c)<=a)
             System.out.println("Not a triangle");
        else if(a==b&&b==c)
             System.out.println("Equilateral triangle");
         else if(a==b||b==c||c==a)
         {
             if((a*a+b*b-c*c<0.000001)||(a*a+c*c-b*b<0.000001)||(b*b+c*c-a*a<0.000001))
                 System.out.println("Isosceles right-angled triangle");
             else
                 System.out.println("Isosceles triangle");
         }
        else if((a*a+b*b)==c*c||(a*a+c*c)==b*b||(b*b+c*c)==a*a)
            System.out.println("Right-angled triangle");
        else
            System.out.println("General triangle");

改进建议:使用的if else语句太多,导致圈复杂度较高,可以使用其他方法去代替if else会让代码可读性更强。

第二次作业7-4

输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。

要求:Main类中必须含有如下方法,签名如下:

public static void main(String[] args);//主方法 
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型 
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
 

输入格式:

在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:

  1. 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
  2. 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日

求下一天中,最先判断的是输入的日期是否合法,其中要区分平年与闰年(isLeapYear(year),判断日期的合法性,需在确定了年份和月份的前提下来推断日期是否合理,将大月小月及二月份分别进行判断,最后得到答案。

   

    {
        if((year>2020||year<1820)||(month<1||month>12)||(day>31||day<1))
            return false;
        else if((month==2&&day>=30)||(month==4&&day==31)||(month==6&&day==31)||(month==9&day==31)||(month==11&&day==31))
            return false;
        else if(isLeapYear(year))
            return true;
        else if(month==2&&day==29)
            return false;
        else
            return true;
    }

 确定了日期的合理性后再来求下一天,先对day进行判断,在day小于30且不属于二月的情况下直接day++即可,当day是一些特殊的情况例如28,29,30,31时,再对月份和年份进行判断,这样按部就班完成下去即可。

 if(day==31)
        {
            day=1;
            if(month==12)
            {
                month=1;
                year++;
            }
            else
                month++;
        }
        else if(day==30&&(month==2||month==4||month==6||month==9||month==11))
        {
            day=1;
            month++;
        }
        else if(day==29&&month==2&&isLeapYear(year))
        {
            day=1;
            month++;
        }
        else if(day==28&&month==2&&!isLeapYear(year))
        {
            day=1;
            month++;
        }
        else
            day++;

改进建议:可用一个数组来表示十二个月的天数,用一个判断条件来确定年份是平年还是闰年,以此来改变数组中第二位数的值,这样可以删去很多if else语句,使代码更简便。

     int[] date = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
     if(isLeapYear(year) == true)
     {
         date[1]=29;
      }

题7-5

输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。

输入格式:

在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。

输出格式:

    1. 当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
    2. 当输入数据合法时,输出“n days ago is:年-月-日”

求前n天中,本题与上题的思路一样,先进行日期合理性以及n的合理性的判断,再来求前n天,在本题里对day,month及year的推导条件变为n+day(n<0)或n-day(n>0),其中的n是n的绝对值,因为现实生活中的前n天和后n天n都是正值,改变+-即可,由n+day或n-day的值来判断month是否要发生变化,再以month的变化来决定year的变化。因为month的不同会导致day的范围的不同,所以一定要结合当前的month与year来判断如何变化,代码如下(取n>0示范)

 

 

if(n>0)
        {
            
               if((n-day)>0&&month==3&&isLeapYear(year))
            {
                month=2;day=29-n+day;
            }
            else if((n-day)>0&&month==3&&!isLeapYear(year))
            {
                month=2;day=28-n+day;
            }
            else if((n-day)>0&&(month==2||month==4||month==6||month==8||month==9||month==11))
            {
                month--;day=31-n+day;
            }
            else if((n-day)>0&&(month==5||month==7||month==10||month==12))
            {
                month--;day=30-n+day;
            }
            else if((n-day)>0&&month==1)
            {
                month=12;year--;day=31-n+day;
            }
            else
            {
                day=day-n;
            }            
        }

改进建议:与上一题基本一致,加一个数组即可。

在第三次作业7-2

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

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

类图.jpg

输入格式:

在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:

  • 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
  • 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日

与上次的求下一天不同的是,需要定义一个Date类,判断是否为闰年,求下一天都是Date类里的方法,其主要思路与第二次作业的7-4大概一致。

改进建议:基于第二次作业7-4上创建一个类即可。

题7-3,

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

输入格式:

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

输出格式:

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

此题较为复杂,我在第一次做此题的时候,因为之前没有接触过正则表达式,迟迟无法用正则表达式将多项式完整表达出来,在我原本的思路中,将一个多项表达式可分为多组,每i组之间都用+或-分开,就是把输入的多项式根据+或-分成几段,每一段又根据*和^分为系数和指数以此来求导,但是实现的时候却并没有那么简单,比如系数的获取,因为输入的是字符串,并不分各十百千位,我需要写一个for语句来把字符转换为系数,并且求导也并不容易实现,所以最后并没有写出来完整的代码。

 

踩坑心得:

1.在第一次作业7-2中,对于取输入的字符串中第一个字符一直用是s[0]来表示,后来通过搜查得知a=s.charAt(0)即可。

        Scanner cin=new Scanner(System.in);
        String s=cin.nextLine();
        char a=s.charAt(0);

2.输出的时候+号与“”号的使用总是出错,变量可直接加+或输出,但其他字符需要以“”包括才能加+或输出;

3.第一次作业7-8中,在判断等腰直角三角形的时候,由于开根号的值为无理数,理论上并不能等于第三条边,因此以a*a+b*b-c*c<0.000001来作为等腰直角三角形的判断。

 

if((a*a+b*b-c*c<0.000001)||(a*a+c*c-b*b<0.000001)||(b*b+c*c-a*a<0.000001))
         System.out.println("Isosceles right-angled triangle");
else
          System.out.println("Isosceles triangle");

4.public class与class的差别,在做第二次作业的时候,在进行类的声明的时候,编写了多个public class的声明,后来报错,搜查得知,一个Java文件中只能有一个public class的声明,但允许多个class声明。

总结与心得:在这三次pta作业中学到了很多,也知道了很多自己的不足之处。我学到了Java的基本构造以及基本语法的使用,类的创建与使用,但是做题时仍然是带着面向过程的思想去思考问题,其实令我印象时刻的不是在pta的练习上,是老师上课讲的那个农夫过河的例子,农夫过河的问题让我初步领会到了面向对象去思考解决问题的那种意思,所以希望老师上课能多讲讲那种例子。

 

 

posted @ 2021-10-15 20:43  cbsldcbsl  阅读(56)  评论(0)    收藏  举报