前三次作业总结

 

前言:

 

学软件果然很累……不过也算学到了比较多东西吧,而且较强的逻辑思维还是救了我一命,至少让我感觉自己学起来理解的更快。(乱讲)

前三次作业真的是步步登天,难度间隔确实大了一点。不过既然上学期学过了一门语言,题目有难度也是正常,需要锻炼的是语法和书写能力了。

第一次作业较简单,前面几道题目都是简单计算简单输出,主要是对基础语法的考察。其中包括一两题在c语言中做过的题,比如计算税率与钱币计算,之前的是非常简单,这两题算比较简单,之后就是7-7对多个数字进行简单排序和7-8判断三角形,主要考察还是对循环语句和判断语句的使用,其大致与c语言相似,所以也算简单吧。

第二次作业难度有了明显提升,没有简单的输入输出,换做c语言估计我也要思索一番。7-1考察对字符串的截取与二进制计算,7-2考察对数组的操作与排序,7-3、7-4和7-5老传统,考察闰年相关,包括输入合法判定、日期计算、闰年计算与判定等等。总体难度中下吧。(刚开学可能脑子不太灵光……

第三次作业难度再次台上新高度,三道题打垮好多人。前两道题难度相当,主要是对类的编写、运行时的创建、如何对类中的数据进行操作、类中设计方法等类相关的知识点。第三题综合性强,需要较大的类体系来实现功能,包括拆分字符串、符号判定、左右0判定、正则表达式的使用、求导去掉1等多个类来实现求导功能(明明求导在数学里那么简单)。第三次作业难度整体高,第三题尤其需要较强的整体逻辑设计思维。

设计与分析:

题目集1:7-8:判断三角形类型

此题只输入三角形三条边,要求判断类型。由于难度不大,就没有将功能分类(坏习惯)。直接写在main方法中了。主要都是if/else语句的书写,需要先对三个数据进行合法判断,若不能形成三角形则提示错误,否则进入形状判断,从最特殊的入手,先是等边,再是等腰直角,再是等腰,再是直角,若都不是则是普通三角形。

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         double a,b,c;
 7         Scanner input = new Scanner(System.in);
 8         a = input.nextDouble();
 9         b = input.nextDouble();
10         c = input.nextDouble();
11         if(a<1||b<1||c<1||a>200||b>200||c>200) {
12             System.out.println("Wrong Format");
13         }
14         else if(a+b<=c||a+c<=b||b+c<=a) {
15             System.out.println("Not a triangle");
16         }
17         else if(a==b&&b==c) {
18             System.out.println("Equilateral triangle");
19         }
20         else if(a==b||b==c||a==c) {
21             System.out.print("Isosceles ");
22             if((a*a+b*b)-(c*c)<1e-10||(a*a+c*c)-(b*b)<1e-10||(b*b+c*c)-(a*a)<1e-10) {
23                 System.out.println("right-angled triangle");
24             }
25             else {
26                 System.out.println("triangle");
27             }
28         }
29         else if((a*a+b*b)-(c*c)<1e-10||(a*a+c*c)-(b*b)<1e-10||(b*b+c*c)-(a*a)<1e-10) {
30             System.out.println("Right-angled triangle");
31         }
32         else {
33             System.out.println("General triangle");
34         }
35     }
36 }
判断三角形

 

单main方法就不放类图了。这里是测试结果。

 

 

 源代码没有很大问题,对于完成功能而言。但是功能还是简单了一点,没考虑输入问题,等腰直角三角形的输入应该是带根号的,无理数的输入没有考虑清楚,所以还是存在小问题。可以将输入设置成String类型,之后进行判定是什么类型数据,要是无理数就使用无理数方法计算,让输入可以带根号,但是目前还不清楚根号怎么用键盘输入,或许用x^-1/2这种形式?(暂定)

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

此题要求输入当天日期,求目标日期的下一天日期并输出。首先要进行判断输入,年份是否超过规定范围、月份是否正常、日期是否超过所在月份的最大天数。在此有一个闰年的判断,若输入的年份是闰年,则需再二月的最大天数上加一天。

 

 

 

需要先定义一个数组monthDay用来存放每个月的最大天数。checkInputValidity用来判断输入年月日是否合法,传入数据,判断结果用boolean型返回。isLeapYear方法判断闰年,同样返回boolean型。nextDate方法用来计算下一天,传入日期后先对day进行判断,如果是当月最后一天则月份加1,day清零为1,再对月份判断,如果是十二月则年份加1,月份清零为1。以下是该方法:

 1 public static void nextDate(int year, int month, int day) {
 2             monthDay[0] = monthDay[2] = monthDay[4] = monthDay[6] = monthDay[7] = monthDay[9] = monthDay[11] = 31;
 3             monthDay[3] = monthDay[5] = monthDay[8] = monthDay[10] = 30;
 4             monthDay[1] = 28;
 5             if(isLeapYear(year)) {
 6                 monthDay[1] += 1;
 7             }
 8             int nextYear = 0;
 9             int nextMonth = 0;
10             int nextDay = 0;
11             if(day == monthDay[month - 1]) {
12                 if(month == 12) {
13                     nextYear = year + 1;
14                     nextMonth = 1;
15                     nextDay = 1;
16                 }
17                 else {
18                     nextYear = year;
19                     nextMonth = month + 1;
20                     nextDay = 1;
21                 }
22             }
23             else {
24                 nextYear = year;
25                 nextMonth = month;
26                 nextDay = day + 1;
27             }
28             System.out.println("Next date is:" + nextYear + "-" + nextMonth + "-" + nextDay);
29         }
nextDate

 

运行测试:

 

没有什么大问题,主要还是代码复杂程度的问题。我认为还可以做成类的形式,制作一个Date类,具有int型数据year、month、day以及nextYear、nextMonth、nextDay,将isLeapYear方法、nextDate方法都放入该类中,checkInputValidity方法放在main类中,这样可以让各方法及属性的调用更加明确简洁。monthDay的赋值也是一个问题,不应该在每个方法调用时都将其进行赋值,可以把它放进Date方法中。但是题目要求必须有这几个方法,不明白可不可以将这几个方法放在别的类里,放在别的类里不知道能不能过题目设置的检查点。

题目集2:7-5:求前N天

此题与前一题相似,主要差距是求的是前N天,N可为正可为负,在计算时会出现day成负数或超过monthDay的情况,则需另外判断。

 

 

主要差距在nextDate方法换成了nDayAgoOfDate方法,也是题目要求的方法。该方法首先判断传入的agoDay数据的正负,正数则计算其前n天,负数则计算其后n天。判断完毕后计算,day加上或减去其值后判断其是否超出限制(1号与该月最大号数),之后操作月份(agoDay正数则减,否则增),再操作年份(与month相同)。以下是该方法具体代码:

 1 public static void nDayAgoOfDate(int year, int month, int day, int ago) {
 2         monthDay[0] = monthDay[2] = monthDay[4] = monthDay[6] = monthDay[7] = monthDay[9] = monthDay[11] = 31;
 3         monthDay[3] = monthDay[5] = monthDay[8] = monthDay[10] = 30;
 4         monthDay[1] = 28;
 5         if(isLeapYear(year)) {
 6             monthDay[1] += 1;
 7         }
 8         int agoYear = 0;
 9         int agoMonth = 0;
10         int agoDay = day - ago;
11         if(agoDay < 1) {
12             if(month == 1) {
13                 agoYear = year - 1;
14                 agoMonth = 12;
15                 agoDay = monthDay[11] + agoDay;
16             }
17             else {
18                 agoYear = year;
19                 agoMonth = month -1;
20                 agoDay = monthDay[month - 2] + agoDay;
21             }
22         }
23         else if(agoDay > monthDay[month - 1]){
24             if(month == 12) {
25                 agoYear = year + 1;
26                 agoMonth = 1;
27                 agoDay = agoDay - monthDay[11];
28             }
29             else {
30                 agoYear = year;
31                 agoMonth = month + 1;
32                 agoDay = agoDay - monthDay[month -1];
33             }
34         }
35         else {
36             agoYear = year;
37             agoMonth = month;
38         }
39         System.out.println(ago + " days ago is:" + agoYear + "-" + agoMonth + "-" + agoDay);
40     }
nDayAgoOfDate

 

以下是测试数据:

问题与上题相似。nDayAgoOfDate这个方法可以改进,不需要根据agoDay的正负而写两套代码,可以在计算的时候进行判断,减少代码行数。

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

此题难度并非特别难,但是较之前的题目又有很大的提升。主要考察还是类的定义,需要在类中将各属性、方法按照题目给出类图一一设计。

 

 题目要求各属性都必须私有,所以要想得到其中年月日信息,就需要相应方法将其返回,故设计getYear等方法返回其值。由输入得到日期需要另设计方法setYear等,将参数的值赋给其对应私有属性。其他方法入isLeapYear、checkInputValidity、nextDate都与之前的相似,主要差别在于它放在Date类中,与各属性同步,需要使用则需调用类。

 1 int getYear() {
 2         return this.year;
 3     }
 4     void setYear(int year) {
 5         this.year = year;
 6         if(isLeapYear(this.year)) {
 7             this.mon_maxnum[2] = 29;
 8         }
 9     }
10     int getMonth() {
11         return this.month;
12     }
13     void setMonth(int month) {
14         this.month = month;
15     }
16     int getDay() {
17         return this.day;
18     }
19     void setDay(int day) {
20         this.day = day;
21     }
得到与输入日期

 

把属性做成私有形式是为了更好的维护数据与防止入侵。私有属性只有在类中能随意调用,在类之外就没有办法查看或更改数据,除非类中定义了相应的方法,如以上的get类方法,就能返回私有属性的值来让类之外的方法或属性了解其值大小。所以,如果想要做到类之外更改私有属性的值是不可能随意做到的,只有类中有方法才能执行此操作。

现在软件与游戏行业中有很多外挂类软件或脚本,很有可能就是钻了这样的空子,随意篡改数据,更改运行方向等等。所以java是一个相对安全的语言,私有属性让他人无从下手,保护了用户的体验。

总结

前三次作业主要还是对输入输出的考察以及类的定义、使用,最重要的还是类相关的知识点。这几次作业让我深刻体会到类是整个java中最重要的结构之一,它支撑了整个java能够自由的使用各种资源,并且程序员能够自由的设计所需要的功能来实现用户需求。像题目集三中的题目,类方便了我们的书写,只要有需求,就设计一个相应的属性或方法去实现,在需要时就调用。类要尽量做到”自己做自己的工作“,比如题目集3的7-3,每个类就只完成自己的工作,切割、转换、主类与函数类,都是”各扫门前雪“,没有非常强的关联,这样能够保证在一个功能出现问题的时候能够快速的找到并修改,各自功能分工明确,那只要找到相应区块就能够找到问题所在。关于类还有太多东西需要去掌握,将来继续努力吧!java可真是太妙了

 

posted on 2021-04-03 23:18  _苏利文  阅读(80)  评论(0)    收藏  举报