第一次博客作业
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***()方法。

浙公网安备 33010602011771号