前三次题目集总结报告
前三次作业总结
一、前言
(1)实验感受
前三次作业总的来说是从c语言到java的过渡,了解到java的主要语法和接触到了类这个概念和使用,Java面向对象的特征主要有封装,继承,多态。类的继承关系是单一的、非多重的。
对于初学者来说,学习Java还是具有一定难度的,能不能学好Java也是看我们能不能适应面向对象的开发。
(2)题目集分析
第一次题目集:实验分为八道题目。
1.考查给a、b赋值,并简单进行运算;
2、考察字符串和数字之间的转换;
3、考察判断和选择来进行条件操作;
4、字符型数据与数值型数据之间的转换;
5、数组的使用、排序方法;
6、循环。
第二次题目集:实验分为五道题。
1、方法的使用;
第三次题目集:实验分为三道题目。
1、考察类的创建和使用;
2、正则表达式的匹配和使用;
3、大数的使用和定义。
总的来说第一次题目难度较为简单,第二次难度稍有提升,而第三次题目难度明显加大。前两次作业很难看到、几乎没有面向对象的身影,但是第三次作业则完全打开了面向对象程序设计的大门。
二、设计与分析
1、首先对于第一次题目集,主要是对Java的输入、输出进行简单使用,和循环判断算法的练习。
关于第一次题目集7-8,它的难度在此次作业中相对有一点难并且复杂一些,它是让我们对三角形进行一个简单的分类。
首先是输入三个实型数赋值于一个数组中,我的思路是将三个数进行排序这样方便匹配“三角形基本原则”,通过选择排序法把三条边从小到大输出。然后用嵌套的if语句和多分支if-else语句将每种情况实现,然后完成此次实验。
在这里要用到数学公式进行求平方,方法是通过Math.abs.()来实现。
圈内复杂度如下图所示:

从这里我们可以看出,由于第一题难度不是很大,所以算法比较单一和简单。第一次作业虽然非常简单,但是具有很大意义。第二次、第三次作业的架构都是在此基础上建立的。
2、第二次题目集考察的是类与对象,主要是针对类的设计和创造。第二次题目集后面几道题都是针对JAVA中的方法的使用,里面涉及到方法的创造和调用,参数的传递和赋值。
对于题目7-4,它要求我们对输入的日期执行输出下一天的操作,首先是在主方法中进行输入,通过isLeapYear(int year);返回boolean类型结果进行闰年的判断以便后面判断闰年二月的天数。
然后通过 checkInputValidity(int year,int month,int day);方法判断输入日期是否合法,在这里判断时将每个月的天数存进数组方便比较,但是注意的是二月的天数有两中情况,所以这时要调用判断闰年的函数来区别这两中情况。
最后,调用nextDate(int year,int month,int day) ;方法求出输入日期的下一天,这里容易漏掉情况,所以写算法时要格外小心。
类大致结构如下图所示:

复杂程度报表:

通过上面的图表可以看出nextDate(int year,int month,int day)函数的复杂程度较高,可能是else-if 语句嵌套使用过多。
对于题目7-5,它要求我们输入年月日的值,然后输出该日期的前n天或者该日期的后n天,同7-4那道题一样,首先判断它是否是闰年用isLeapYear(year);
再通过数组将每个月的天数传进去,用来判断是否输入的数据为合法数据,然后进行日期的输出,由于情况很多,并且有点复杂,容易漏掉闰年这个点,导致二月份的天数判断错误。考验的就是对题目的理解和心思缜密。
圈复杂度如下图所示:

主方法的复杂程度过高,代码差点就没有可读性了,和上面题目的原因一样,由于if-else语句嵌套使用过多。所以以后要简化if-else语句,尽量避免过多嵌套。可以改用switch。
3、第三次题目集考察的类的创造和值的传递,类的使用方法和好处。后面题目难度提升了很多,不仅是算法,重要的语法的学习和使用。
下面是我对类的使用好处的一些看法:
结构清晰,易于维护。面向对象将类中的信息进行封装,即将属性等和函数绑在一起。调用时很容易知道函数来自于哪个类
1、易维护
采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的。
2、质量高
在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求并具有较高的质量。
3、效率高
在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
4、易扩展
由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。
对于题目7-2,要求输出所输入日期的下一天,和题目集二7-4题目不同的是这次要求对参数的封装,需要建立一个Date类来执行相关操作。通过getter和setter获取主类中获取的值,包括 year, month, day,mon-nextnum[]。 在这里我认为最关键的也是必要的是对参数值的传递和修改,在类中修改有利于后期查找和修改起来更方便。
类图如下图所示:

如上图所示:首先创建Date类来对功能进行实现,主方法中获取参数 year day
month的值,Date类中定义私有类型进行封装保护。分别创建无参构造法和有参构造法,
在主方法中调用此类,将类之间联系起来。
圈复杂度如下图所示:



综合上面的图和7-4题目对比很容易得到,代码复杂度明显降低,由此可以看出使用类的质量高,效率高。
对于题目7-3,要求我们编写程序性,实现对简单多项式的导函数进行求解。这道题考察的知识点很多,其中引用了大数语法,还有正则表达式。
关于正则表达式,正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式可以用来检索、替换那些符合某个模式(规则)的文本;可以通过一些设定的规则来匹配一些字符串,是一个强大的字符串匹配工具。
如图所示是正则表达式的简单使用:

这道题的解题思路是先用正则表达式匹配检索所输入的表达式是否合法,对于表达式中含有的空格使用replace all()除去。然后建立一个Solve类,用来实现功能。在Solve类里面通过另外一个正则表达式来获取多项式中的每一项存入数组arr[ ]中,再使用循环对数组中的元素进行单个操作,分别用正则表达式匹配乘号和指数符号,作为分界点来获取之前或者之后的数字字符串。“*”号之前是系数,“^”之后是指数。获取两个数字之后,分别赋值于a和b,然后对a和b进行大数转换。随后对a b数值进行操作,计算出最后求导的表达式再输出。
在这里由于情况有许多种,例如:系数为 1 时的时候,可以省略系数或表示为正号开头的形式,如 x^-2系数为-1 时的时候,可以表示为符号开头的形式,如-x^3。这些情况都要单独取出来进行求导数运算。
类图如下所示:

由上图可知,我只进行了所输入字符串的传递。其他数组、变量的声明和创造都是在Solve类中进行。
圈复杂度如下图所示:

由上图所知,getanswer( )方法的复杂度过高,因为我用if-else嵌套,导致赘余并且所判断情况太多,目前我还没找到有什么好的方法能实现,因为改动会导致算发法结果发生改变。
三、采坑心得
1、语法错误:通常,编译器对程序进行编译的过程中,会把检测到的语法错误以提示的方式列举出来。
主要有括号不匹配,变量未声明(此类错误最多)如下图:

数据类型之间的转换。例如String输入,int or double输出时。如下图:

我认为出现此类错误是好解决的。此类错误一般程序编译系统会自动提示相应的错误地点和错误原因,比如哪一行代码少了个括号等诸如此类的提示,常见的错误,看懂直接改正即可,如果是看不懂原因,可以将错误提示信息输入搜索引擎查找一下,一般都能找到具体的解决办法。需要的是多练和细心。
2、逻辑错误:由于编译器无法检测出存在的逻辑错误,所以此类错误有点麻烦。
主要有遗漏可能出现的情况。例如题目集三7-3,容易漏掉第一项系数为负数的情况,还有指数为2的时候。
题目集二的7-4,容易遗漏闰年的二月。
还有循环条件错误,指令的次序错误,程序设计算法考虑不周全等,尤其是当题目所涉及的情况较多时容易遗漏。在一般情况下,编译器在编译程序时,不能检测到程序中的逻辑错误,也不会产生逻辑错误的提示,因此逻辑错误比较难排除,需要我们仔细的分析程序,并借助集成开发环境提供的调试工具,才能找到出错的原因,并排除错误。
3、运行错误:运行时被迫中止且编译器开始不能产生提示。
主要有数组元素超出范围。(主要报错:ArrayIndextOutOfBounds数组下标超出边界)如下图:

方法的使用前后不匹配或找不到所要的头文件,如下图:

此类错误发生时,编译平台一般也会提示相应的信息,对于常规的错误会有比较精确地提示,但有时提示的错误原因会比较模糊,但因为此类错误一般在程序运行时,只在特定的条件下才会发生,所以根据错误发生的条件,能够大致判断程序出错的代码段,结合错误的原因,也能比较方便的调试出错误。
四、改进建议
(1)对于题目集二7-4、7-5和题目集7-3,由于if-else语句嵌套过多导致代码过于复杂,可以考虑使用相似逻辑进行判断的一般情况下可以使用switch语句进行取代,可以使得代码可读性更高。
(2)对于功能复杂的代码可以建立多个类来实现,这样可以容易修改和调整,增加代码可读行。
五、总结
1、学到了什么
首先是正则表达式,包括正则的效率问题,了解到正则表达式的巨大作用。
这些题目集让我学习到类的设计的重大用处。
了解到什么是封装:就是将类的信息隐藏再类的内部,不允许外部程序进行直接访问,而是通过类的内部方法进行访问和操作。
如何实现封装:
1.首先将属性的修饰符设为private,限制访问;
2.生成getter/setter方法;
3.对getter/setter方法进行属性控制,如判空,逻辑操作等;
对于进一步研究方向,我认为简化代码复杂度和学习更好的算法是接下来的学习方向。

浙公网安备 33010602011771号