第一次博客作业

1.前言

本学期为第一次接触和学习Java,与之前的C语言不同,Java语言中没有指针的概念,但并不是没有指针,虚拟机内部还是使用了指针,只是让编程者无法找到指针以直接访问内存,提高了Java程序的安全性。在Java语言里面强调面对对象程序设计,主要以对象的角度构建程序,使用类来建模对象。面对对象编程的主要特征有封装性,继承性,多态性。

习题集总结

知识点

本月题目集主要涉及一些新知识点,在C语言的基础上转变输入输出语句等格式还是轻而易举,学到更多的是Java的类的构建,如何体现类的封装性,即使用private 修饰类的成员变量定义它的访问权限,让外面的类不能随意修改其他一个类的成员变量。对类的变量读取和赋值操作一般使用get***()和set***()方法。

一个类就是一个模块,我们仅仅只能公开类需要让外部知道的东西,然后隐藏所有其他的部分。

题目集题量

对于本月题目集,题目简单则题数增加,题目较难则题数减少,题量布置十分合理到位。

题目集难度

前三次题目集整体较简单,题目集内题目难度呈递增趋势,三次题目集之间难度也呈逐渐增长趋势,难度递增符合大多数学生认知,能让学生在解决困难和问题中不断学习和磨砺。

2.题目设计与分析

第一次题目集7-8

题目情况

题目要求判断三角形的形状,包括等边,等腰非直角,等腰直角,直角,一般三角形以及非三角形的八种情况。

设计思路

输入数据不合法则则输出Wrong Format,否则进行下一步判断,若不满足形成三角形则输出Not a triangle,然后判断是否为等边,在判断是否为等腰,若为等腰则继续判断是否为直角,若不为直角则进行下一步非等腰直角三角形的判断,若上述条件均不满足则为一般三角形。

源码分析

思路简单,依次判断,但内容冗余啰嗦,多次if嵌套,圈复杂度高,代码质量低。

 

第二次题目集7-4

题目情况

输入年月日的值(均为整型数),输出该日期的下一天。

设计思路

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) ; //求输入日期的下一天

在主方法中根据调用isLeapYear()方法返回的boolean值进入下一步,若返回true则调用nextDate()方法,否则输出Wrong Format。

在neatDate()方法中定义m为二月的天数,调用isLeaoYeaar()方法对m进行修改,相比之前的在if语句里进行判断闰年可以减少一个if语句,减少代码复杂度。在switch()语句中,根据月份进行不同的运算,将情况相同的月份放在一起,特殊情况的单独一部分,例如求二月或者十二月某一天的下一天。利用switch的特性与break的合理结合,使得代码与之前ifx语句写的更加简洁美观,复杂度更低。

源码分析

题中未要求使用类,没有使用类进行,并未体现面对对象编程。在主类中构造了三个方法,分别对日期进行不同的操作,代码的核心部分均使用switch语句实现,取消使用以往熟练的if语句,简化了代码,提高了质量。

 1 public static void nextDate(int year, int month, int day) {
 2         int m = 28;
 3         if (isLeapYear(year))
 4             m = 29;
 5         
 6         switch (month) {
 7         case 11:
 8         case 9:
 9         case 6:
10         case 4:
11             if (day == 30) {
12                 day = 1;
13                 month++;
14             } else {
15                 day++;
16             }
17             break;
18 
19         case 12:
20             if (day == 31) {
21                 day = 1;
22                 month = 1;
23                 year++;
24             } else {
25                 day++;
26             }
27             break;
28 
29         case 10:
30         case 8:
31         case 7:
32         case 5:
33         case 3:
34         case 1:
35             if (day == 31) {
36                 day = 1;
37                 month++;
38             } else {
39                 day++;
40             }
41             break;
42 
43         case 2:
44             if (day == m) {
45                 day = 1;
46                 month++;
47             } else {
48                 day++;
49             }
50             break;
51 
52         }
53         if(checkInputValidity(year, month, day)) {
54             System.out.println("Next date is:" + year + "-" + month + "-" + day);
55         }else {
56             System.out.println("Wrong Format");
57         }
58     }

 

 

 

 

 

 第二次题目集7-5

题目情况

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

设计思路

构造三个方法如下

public static void nextDate(int year, int month, int day, int n) //求输入日期的前n天

public static boolean checkInputValidity(int year, int month, int day) //判断输入日期是否合法,返回布尔值

public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型

核心代码:求输入日期的前n天

将情况相同的月份放在一起,特殊情况的单独出来。对应不同正负的n相应的考虑不跨月的以及跨月的求值情况。

 1 public static void nextDate(int year, int month, int day, int n) {
 2         int m = 28;
 3         if (isLeapYear(year))
 4             m = 29;
 5         switch (month) {
 6         case 11:
 7         case 9:
 8         case 6:
 9         case 4:day = day + n;
10         if(day <= 0) {
11             day = 31 + day ;
12             month--;
13         }else if(day > 30) {
14             day = day -30;
15             month++;
16         }break;
17 
18         case 12:day = day + n;
19         if(day <= 0) {
20             day = 30 + day ;
21             month--;
22             
23         }else if(day > 31) {
24             day = day -31;
25             month = 1;
26             year++;
27         }break;
28         
29         case 8:day = day + n;
30         if(day <= 0) {
31             day = 31 + day ;
32             month--;
33             
34         }else if(day > 31) {
35             day = day -31;
36             month++;
37         }break;
38             
39             
40         case 10:
41         case 7:
42         case 5:day = day + n;
43         if(day <= 0) {
44             day = 30 + day ;
45             month--;
46             
47         }else if(day > 31) {
48             day = day -31;
49             month++;
50             
51         }break;
52         
53         case 3:day = day + n;
54         if(day <= 0) {
55             day = m + day ;
56             month--;
57             
58         }else if(day > 31) {
59             day = day -31;
60             month++;
61             
62         }break;
63         
64         case 1:day = day + n;
65         if(day <= 0) {
66             day = 31 + day ;
67             month = 12;
68             year--;
69         }else if(day > 31) {
70             day = day -31;
71             month++;
72             
73         }break;
74 
75         case 2:
76             day = day + n;
77             if(day <= 0) {
78                 day = 31 + day ;
79                 month--;
80                 
81             }else if(day > m) {
82                 day = day - m;
83                 month++;
84                 
85             }break;
86         }    
87         n = -1*n;
88         if(checkInputValidity(year, month, day)) {
89             System.out.println(n + " days ago is:" + year + "-" + month + "-" + day);
90         }else {
91             System.out.println("Wrong Format");
92         }
93     }

 

源码分析

在求下一天时,将输入的天数day与n相加赋给day,对day进行分析,若day小于零则在上个月的总天数上减去day,并将月数减一(若为一月则月数赋值12,年数减一),若day大于当月总天数,则day减去当月总天数,并将月数加一(若为十二月则月份赋值1,年数加一)。使用switch对不同月的求天数进行相应操作,提高代码质量。

 

 

 

第三次题目集7-2

题目情况

定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 

设计思路

将日期作为类进行封装,定义私有变量year,month,day以及mon_maxnum。

外部可通过get***()方法进行访问该类。

体现面向对象编程类的封装性。

 

 

源码分析

Date类复杂度较高,主方法复杂度低,说明降低复杂度可以把相应功能包装成类方法。

 

Date类复杂度分析

 

 

主方法复杂度分析

 

 

第三次题目集7-3

题目情况

 

设计编写程序,实现对一元多次简单多项式的导函数进行求解。

设计思路

定义一个类对字符串去空格,将带有空格的一元多次多项式字符串进行去空格操作,然后再进行合法性检验和是否为常数的判断,若为常数则输出0,若不合法则输出Wrong Format,程序结束,否则继续进行程序。

将字符串进行提取每一项操作,取出所有项(包括常数项)放到类中。

在实体类项中定义指数zhishu,系数xishu,项str,状态变量zhuangtai,项数index。其中系数和指数定义为BigInteger类型,方便多超多位数的数值进行求导操作。其中项数index方便判断在输出结果的开头不加“+”符号。

类xiang中方法jisuan()在对项操作时,对项与每种类型的正则做比较,共有a*[+]?x^b,a*-x^b,[+]?x,-x,-x^b,[+]?x^b六中情况,若与其中任何一种无法对比上则zhuangtai变量赋值为1,否则仍为0,在对比上其中一种情况后会对项进行提取系数,指数操作,若项里面的x带有负号则在提取的系数乘以-1。

类xiang中方法getjieguo()对项进行求导,将在jisuan()中提取的系数和指数进行运算,得到新的系数sum和指数zhishu,对系数和指数以及项数进行讨论判断输出的格式。

源码分析

 

在jisuan()方法中对项进行对比时效率不高,主要是对比时是对每一项与设定好的情况进行比较,应对项中的关键信息进行用正则对比,例如判断项是否含x,若有x再判断x前是否有系数或者指数。

在getjieguo()方法中对新系数sum和新指数zhihsu的判断中使用了大量if语句进行嵌套,这样做思路简单但效率低下。

 

类结构图

 

源码复杂度分析

 

 

3.心得

在第三次题目集的第三题中收获颇丰,在该题中主要学会正则的使用。

正则的使用有非常多的技巧,要想精通可谓一件难事。

在求导题目中,我首先使用String的split()方法对字符串进行分割,以“+”为分割符,但在仔细观察输入样例后发现该方法并不适用,因为输入的字符串含有“+”开头的项,也有“-”开头的项,用“+”根本无法分割,再改用“x”作为分割符后发现也不好使,毕竟有的项没有x,分割后每组字符串含有的数字个数不相同。后来改成正则去取出每一项,存入定义好的类数组中,在类中对项进行分类和求导的操作。

在进行合法性检验操作因粗心导致合法格式也输出不合法,发现该问题时在进行大数测试时输入20000000000000000000*x^5测试是否能输出相应长位数的结果时输出Wrong Format ,此时我检查合法性检验部分顿悟,原来是符合“0*x”格式的均会判定为Wrong Format 。

 

错误如下图所示

 

 

正确输出应如下

 

 (ps:一个对细节不敏感的程序员不是好程序员,细节很重要。)

 

4.改进建议

在一元多次多项式求导题目中有很多需要改进的地方,主要为三个。

1.对主类中的合法性检验功能包装成类,可以与去空格类DeleteBlank写在一起,成为一个新的类。

2.在类xiang中的jisuan()方法中,需要简化对项的分类,避免项与每一种情况一一对比。

3.在类xiang中的getjieguo()方法中,对指数zhishu和系数xishu以及项数index的判断使用较多if嵌套,需要简化,使用switch语句来代替。

5.总结

在本月题目集学习知识颇丰,主要包含Java类的封装性和正则表达式的使用。

在定义类时要对属性进行private私有符修饰,在外部访问时通过set***()和get***()方法。

posted @ 2021-04-04 22:56  wendying  阅读(110)  评论(0)    收藏  举报