前三次题目集总结

一、前言

  首先,对于这三次题目集,我的收获挺多。在第一次题目集中,主要是一些较为基础的Java语法特性,有简单数据的输入输出,对字符及字符串的简单运用,然后就是一些简单的if语句判断和一维数组的简单运用以及简单的排序;在第二次题目集中,难度相对于第一次有所增加,这次的题目主要就是一些排序问题和判断的问题,例如是否为闰年的判断,以及每个月天数的判断,其次就是对于输入数据是否正确的判断,这些都是本次题目集要认真考虑清楚的点,不能随意乱写;最后就是第三次题目集了,同时也是三次作业中最难的一次,在本次作业中主要就是锻炼我们在编写Java程序时多使用类来处理问题,这样可以便于我们在后期对代码进行修改的过程中可以对有问题的类进行修改,而不用我们对整个一大串代码全部看一遍找问题了,也对类里面的数据进行过public和private的处理,同时锻炼了我们对于输入正误的判断运用正则表达式来判断。简而言之,这三次题目集中,第一次题目集共有8道题目,但是题目还算比较简单,第二次题目集减少到了5到题目,题目的难度也有所提高,而在第三次的题目集中,题目的数量虽然比前两次都少,只有3道题,题量少,但是难度还比较大,用到的东西比较多,需要判断的东西也比较多。对这三次题目集的总体题量和难度来讲,感觉这三次题目的设置还比较合理,在题量多的时候,难度稍微简单;在题量少的时候,难度便稍微提高。感觉这三次的题目集总体情况还可以,还比较好处理。

 

二、设计与分析

(1)题目集1:7-8

  对于题目集1:7-8,是编写一个程序,用于判断三角的类型。这道题目我的代码使用的方式较为简单,就是简单的if语句判断,对于符合每一种情况的三角形进行判断,当符合每一种时就输出哪种三角形,首先是判断输入的数据是否合法,再者判断能不能构成三角形,其次判断是否为等边三角形,然后判断是否为等腰直角三角形,然后就是判断是不是等腰三角形是不是直角三角形,剩下的就是普通的三角形了。

由于没有当时没有类的概念,便只有一个主类,如下:

(2)题目集2:7-4

   对于题目集2的7-4,是编写一个程序求输入日期的下一天,对于这题,首先要判断输入的年份是否合理,其次要对是不是闰年进行判断,因为闰年的2月有29天,并且对于每一个月的最后一天要进行特殊判断,因为下一天是下个月的第一天,不是简单的日期加一;要做到对日期的全面考虑。相关图片如下:

 

(3)题目集2:7-5

  对于题目集2的7-5,是求输入日期和输入N值后的前N天,首先的考虑方法和上一题一样,但是要注意N的不同取值代表的所求结果会有所不同,当N大于0时,结果是往前的N天,但是N小于0时则是当前日期的后N的绝对值天,当然,N=0时日期不变,做该道题目时想清楚这些就没问题了,代码相关的图片如下:

(4)题目集3:7-2

  对于题目集3的7-2,是定义一个日期类来进行求解下一天,由题可知,该日期类包含有3个私有属性year,month和day,还有11个public属性,其实解该题不会难,只要把题目上面的类中的属性全部都写好、写全,解该题就十分简单了,注意一些细节就可以完成了;与代码相关的图片如下:

(5)题目集3:7-3

  对于题目集3的7-3,是要对一串的简单多项式进行求导,其中还可能有输入错误的数据类型,所以我想到的是将输入的一连串字符串进行判断,确定是正确的式子后再对其进行,所以我选择使用正则表达式来对其先进行判断,在判断正确之后,再对符合正则表达式的式子进行每一个的拆分,分成每一个项之后再采用BigInteger,这个BigInteger是为了将数字和符号分离,更加有利于后面的求导,当数字准备好了之后,就可以对每一项进行相应的求导工作,但是求导之后要注意去判断每一项的符号,一定要注意符号的问题,可以会出现漏符号或者多符号的问题,所以我就采用了对特殊情况进行特殊的判断,这样将有利于我的符号判断,但是,由于我只写了一个类来解决这个问题,所以当后面我去修改程序的时候发现自己写的程序很是混乱,改起来也无从下手,让我深刻认识到类的重要性,以下是代码的相关图片:

 

 

三、踩坑心得

(1)对于题目集1的7-8,在编写代码的过程中,判断三角形的类型,首先应该想到符合成为三角形的条件,再对特殊的情况进行特殊的判断,但是在判断能不能是直角三角形或者是等腰直角三角形的时候,我们不能直接用如下的代码,是因为在Java中,涉及浮点数的计算都是近似的,因为这些数没有以准确的精度来储存,所以对于判断直角就不能直接就使用下面的这种判断来; 

1 if(a*a+b*b==c*c||b*b+c*c==a*a||c*c+a*a==b*b) 

而应该用比较大小的方式来判断,就好比我用于判断是否为等腰直角三角形的代码一样,应该使用下面的这样的代码(仅供参考):

1 else if(a==b&&a*a+b*b-c*c<0.0001||b==c&&b*b+c*c-a*a<0.0001||c==a&&c*c+a*a-b*b<0.0001)
2                 {
3                     System.out.println("Isosceles right-angled triangle");//输入数据合法且能够成等腰直角三角形
4                 }

对于题目集1的7-8,以上的坑应该就是这道题最大的坑了,这个点比较难想到,其次就是建议尽量按照题目的判断来进行编写程序,这样编写出来的程序逻辑性比较强,更有利于后续检查程序。

(2)对于题目集2的7-4,是求解输入年份的下一天,其实这题并不是很难,只要思维逻辑很清晰,就很容易编写出这题的代码来,要注意输入的日期的合法,年份区间和月份的正确,比较难处理的应该就是对应每个月的天数的判断了,因为每个月的天数都不一样,而且特别是判断闰年的二月的天数,又要判断是不是闰年,而且还要注意2月时的天数的输入是否合法;并且当输入的是每个月的最后一天时,又得进行一下特殊的判断,月份加一,然后将日期改成一号,对这些点进行了判断和分析,这道题也就不怎么难了,下面是我2月份求下一天的相关代码(仅供参考):

 1 if(month==2)
 2         {
 3             if(isLeapYear(year)&&day==29)
 4             {
 5                 month=3;
 6                 day=1;
 7             }
 8             else if(!isLeapYear(year)&&day==28)
 9             {
10                 month=3;
11                 day=1;
12             }
13             else
14             {
15                 day=day+1;
16             }
17         }

(3)对于题目集2的7-5,其实和题目集2的7-4很像,7-4是求下一天,而这个7-5则是求前N天,注意N的取值范围即可,同时对于求前N天种的可能出现跳月的现象就要多多注意,比如3月跳至二月时就要注意该年是不是闰年,在二月份中是从28日算起还是从29日算起,同时当N为负值时,则所求的天数应该是往后计算,而不是往前计算,其他的需要注意的点大致上和题目集2的7-4差不多,注意逻辑思维的运用好就可以,下面给出N为正数且为3月时的判断代码(仅供参考):

 1 if(month==3)
 2             {
 3                 if(isLeapYear(year))
 4                 {
 5                     if(day<Math.abs(n))
 6                     {
 7                         month=2;
 8                         day=29+day-Math.abs(n);
 9                     }
10                     else
11                     {
12                         day=day-Math.abs(n);
13                     }
14                 }
15                 else if(!isLeapYear(year))
16                 {
17                     if(day<Math.abs(n))
18                     {
19                         month=2;
20                         day=28+day-Math.abs(n);
21                     }
22                     else
23                     {
24                         day=day-Math.abs(n);
25                     }
26                 }
27             }

(4)对于题目集3的7-2,是定义一个关于日期的类,并且求出输入日期的下一天,该题的题目要求的结果是和题目集2的7-4一样的,都是求下一天,但是该题目是要用类的方法来求解,需要我们设计类,在类设计中,同样需要精确地判断每一个输入日期的合法性,要在Date类里面全部实现,切记以后做题一定要认真看清楚题目的要求,我就没看清楚题目的要求,就大致看了一下需要求的结果是什么样的,我就一味地找到题目集2的7-4,并且将相关的代码copy上去了,导致我一直有一个点没有过,而且是一个十分低级的错误,在题目集2的7-4中,所求年份的区间为[1820,2020],而在这道题目里面的年份区间为[1900,2000],导致我一直在找自己程序的错误,最后才发现原来是题目没有看清,所以切记,以后做题一定不能看题目看一个大概,而是要认认真真地看清楚来,尽管题目可能大致一样,但是最后也可能在一个很细微的点让自己陷入沉思,所以一定要认真看题目!认真看题目!认真看题目!!!其次就是类里面的setter和getter的方法的使用,这两个点的使用还算是比较简单的,上课认真听老师讲课或者课后自己认真看书,都是可以看懂的,不难,但是一定要认真学习。由于该题只是题目集2的7-4的类的设计,基本也就没有什么编写程序方面的问题,若有什么问题可以参考上面题目集2的7-4的心得,这题我踩的坑就是我看清楚题目,吃一堑长一智。以下是主类的代码(仅供参考 ):

 

 1 public class Main {
 2 
 3     public static void main(String[] args) {
 4         // TODO 自动生成的方法存根
 5         Scanner input = new Scanner(System.in);
 6         Date date = new Date();
 7         date.setYear(input.nextInt());
 8         date.setMonth(input.nextInt());
 9         date.setDay(input.nextInt());
10         if(!date.checkInputValidity())
11         {
12             System.out.println("Date Format is Wrong");
13         }
14         else
15         {
16             date.getNextDate();
17         }
18     }
19 
20 }

 

(5)对于题目集3的7-3,是一个比较难的一元简单多项式的导函数求导问题,对于处理这个问题,我并没有完全将代码调试完成解全部的点,有一些特殊的情况没来得及考虑,但是,说实话,解决这道题目最关键的就是学好正则表达式,正则表达式对于判断数据输入是否正确极为重要,当然也是比较好学的,只要对老师的讲解或者自己看书,一般都可以很轻松地拿下正则表达式,当然,我自己最后还是在bilibili上面找到的教学视频看,可以访问//www.bilibili.com/video/BV1Ft4y1q7Vm?p=2进入bilibili里面学习正则表达式,但仅供参考,具体看自己的实际情况。下面是我的判断是否符合为简单多项式的正则表达式(仅供参考): 

1 String regexr2 ="(([-+]?[0]+)\\*x\\^([+-]?[\\d]+)"
2                 + "|([-+]?[0]+)\\*x"
3                 + "|[x]\\^([+-]?[0]+)"
4                 + "|([-+]?[\\d]+)\\*x\\^([+-]?[0]+))";

还有一种常量的正则表达式建议自己去摸索,比较简单,使用正则表达式就比较简单地可以判断输入数据的正误,更加利于我的判断;其次就是求导的问题解决,可以使用拆分成数组的形式来计算当然也可以用正则表达式里面的Pattern和Matcher来将那一大串的输入数据分解成每一项进而求解,同时使用BigInteger方法应该也更加便捷,具体使用还看自己。但是由于我并没有将这道题完整地解出来,所以也不知道后面是否还有难过的测试点,解到现在发现的问题基本上就这样。

 

四、改进建议

(1)题目集1的7-8,比较简单,当然也可以在后续的过程中可以对一般的三角形进行角度的判断,进而对一般的三角形做到钝角和锐角的判断,更加有利于对三角形的形状做进一步的区分,使得程序更加可行。

(2)题目集2的7-4,在后续和同学交流的过程中,发现了自己的代码有bug,我只是对2月的日期进行了判断,但是对于那些月份只有30天的月份并没有进行判断,这是我在这道题目中发现的我的bug,如下图:所以我的代码其实是不够完整的,我应该将我的代码日期判断那部分重新编写。

(3)由于我的题目集2的7-5是仿照上一题写的,所以上一题出现的问题在这一题也有,对于这一题,我认为N的区间可以扩大一点范围,可以不用[-10,10],范围可以跨月多一点,这样就会使该程序的可行性更加高。

(4)题目集3的7-2和题目集2的7-4是一样的,但是使用了类的概念,这样对于修改程序,使程序修改完整更加方便。

(5)题目集3的7-3题目我没有写完,但是结束后问同学便发现自己是少了一些特殊情况的判断,导致我的程序有一些测试点过不了,程序不够完整,代码的解题思维还不够强,这道题目十分锻炼我们的逻辑思维和解题思维。

 

五、总结

  在这三次的题目集中包含的内容很多,前2次的作业比较偏向于基础,第一次的就是将之前学的C语言的编程用Java来写出来,这样,可以让我们熟悉Java的编程方式以及复习一下C语言的相关知识,巩固我们基础知识,同时在第一次作业中收获到了在Java中,涉及浮点数的计算都是近似的,因为这些数没有以准确的精度来储存,在以后这个可以作为一个知识点来记忆,并且在第一次作业中我了解到Java可以使用一个排序的方法Arrays.sort();可以直接排序,让我进一步感受到了Java语言为什么在编程语言中如此受欢迎的原因,也觉得感受到了Java语言的强大功能;在第二次作业中,我们开始接触到一些关于Java的函数,例如Math.pow;Math.abs;等等一些常见的数学函数,同时在第二次作业中也特别能锻炼我们的逻辑思维能力,在第二次作业中,有3道关于年份的判断,还有一道关于IP地址的转换,这都十分考验我们的逻辑思维能力和思考的全面性,第二次作业也还不错;第三次作业虽然说是难了一点,但是第三次作业感觉才更加有Java的味道了,第三次作业的前两道题目,虽然都是比较简单的题目,都是要求我们采用Java中类的使用来解题,采用类的方式来解题,让我明白了为什么Java使用类这一特性的原因,使用类可以让我们在程序调试的过程中发现是哪个类有问题,而不用将整个代码全部看一遍,可以精确定位到是哪个类出了问题,有利于程序在修改的时候更加方便,对每一个不同的类属性进行筛选,与此同时,在使用类的过程中,让我学会了使用Java里面的setter和getter方法,同时也懂得了private,public和protected的使用场所、使用方法以及它们之间的区别,对于boolean类型也有了更加深刻的了解,第三题则是最难的一道题目了,同时也是收获最多的一道题目了,在解决这道题的过程中,我学到了正则表达式是运用,发现正则表达式对于判断数据是否输入正确十分便利,在以后的编程过程中也肯定是十分有帮助的,其次我还使用了正则表达式中的Pattern和Matcher,并且使用了find和group来对简单多项式进行拆分,最后还使用了BigInteger来对每一项的数据进行分类和求导,这次作业锻炼了我的逻辑思维,并且利于我来使用Java来进行编程的思想。

  总的来说,这三次给了我许多的帮助,让我了解到Java语言给程序员的巨大便利,同时也锻炼了思考问题的能力,加强了我的逻辑思维,获益匪浅。