目录
前言:
这学期才接触Java,以前只学过C语言。所以Java的面向对象对我来说非常神奇,也非常难。经过这三次的大作业可以确定Java真的很高级。Java的通用性很好,可以跨平台直接移植,只要安装Java虚拟机就可以了。开发的效率高。生成的机器码效率没有汇编和C的高。在嵌入式系统中,C语言是使用最广泛的语言。
Java的语法我现在才开始适应。下面就简单总结一下这三次题目集的知识点和难度情况吧!
第一次作业:作业的知识点是学习C语言的时候学过的内容主要就是一些简单的计算、求和、字符串的处理等。另外涉及到了Java的基础语法,但是还没有涉及到面向对象的设计。题量相较于第二、三次作业较大,但是难度不大,比较好完成。最最糟心的是:总会有一两个题的一两个测试点过不去.......说明我的程序还有漏洞,要加以改进。
第二次作业:题目只有四个,但是对当时的我来说难度比上次的难度大了不止一个档次。第一、二题开始使用面向对象的一些思想(刚开始从C语言的对过程转向Java的面向对象思想可想而知是多么痛苦)。第三题是判断合法日期、计算两个日期之间相差了多少天数、月数和年数,这里主要用到了Java里面的Calendar、LocalDate和Date类(Java真智能)。第四题小明走格子,这个题目的计算方法有很多,但是最难的是如何做到不运行超时,这就要用到Java里面的StreamTokenizer读取输入方式,而不是Scanner。前者是在数据量输入特别大时使用,后者是日常少量数据情况下使用。前者的读取数据的速度比后者更快。
第三次作业:第一题还是菜单系列的题目,增加了桌号和带点的功能(好多测试点没过,圈复杂度太大,耦合度太高,太痛了)。后面第二、三、四题是对重复数据和字符串的处理,这里要用到Java里面的:
①HashSet集合(哈希集):元素无序,不可重复;
②List集合:元素有序,可重复;
③Arraylist类:一个可以动态修改的数组,没有固定大小的限制;
④LinkedHashSet:HashSet的有序版本;
⑤Collections.sort():是对List对象进行排序的工具方法。
第五题运用到了Java里面的封装性。第六题运用到了类型转换。第七题是日期判断,主要用到LocalDate类中of()、ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。
设计与分析:
第一次作业:
第一题:7-1 身体质量指数(BMI)测算
类图:

耦合度、圈复杂度:

Statments(有效语句):21行
Percent Branch Statements(分支语句比例):28.6
Maximum Complexity(该类中最复杂函数的复杂度):12
由Kiviat Graph图可知:最大复杂度和平均复杂度超过绿色范围,复杂度过大,代码不合格,需要改进。
if(high>2.72||weight>727||high<=0||weight<=0) System.out.println("input out of range"); else { if(bmi<18.5) System.out.println("thin"); if(bmi>=18.5&&bmi<24) System.out.println("fit"); if(bmi>=24&&bmi<28) System.out.println("overweight"); if(bmi>=28) System.out.println("fat"); }
该代码用了五个if,复杂度太大。
优化:
if(bmi<18.5) { System.out.println("thin"); return; } else if(bmi<24) { System.out.println("fit"); return; } else if(bmi<28) { System.out.println("overweight"); return; } else if(bmi>=28) { System.out.println("fat"); return; } System.out.println("input out of range");
第二题:7-2 长度质量计量单位换算
类图:

耦合度、圈复杂度:

Statments(有效语句):12行
Percent Branch Statements(分支语句比例):0.0
Maximum Complexity(该类中最复杂函数的复杂度):1
由Kiviat Graph图可知:该代码的平均复杂度、最大复杂度、最大函数深度都在绿色范围内,表示良好。该代码不需要进行判断,没有分支,只需注意换算的要求,进行类型转换,注意格式即可。
第三题:7-3 奇数求和
类图:

耦合度、圈复杂度:

Statments(有效语句):13行
Percent Branch Statements(分支语句比例):15.4
Maximum Complexity(该类中最复杂函数的复杂度):3
由Kiviat Graph图可知:该代码的平均复杂度、最大复杂度、最大函数深度都在绿色范围内,表示良好。唯一缺点是:还是面向过程的思想,应该尝试转换为 面向过程的思想。
for(i=0;i<10;i++) { a[i]=sc.nextInt(); if(a[i]%2!=0) sum+=a[i]; }
优化:用面向对象的思想:
类的属性:自然数
类的方法:
①判断是否为奇数 Boolean panduan(int a);
②相加求和 int add(int[ ] a);
第四题:7-4 房产税费计算2022
类图:

耦合度、圈复杂度:

Statments(有效语句):23行
Percent Branch Statements(分支语句比例):21.7
Maximum Complexity(该类中最复杂函数的复杂度):7
由Kiviat Graph图可知:该代码的Avg Complexity(平均复杂度)和Avg Stmts/Method(平均一个函数包括的语句数目)超过范围。
int n=sc.nextInt(); int m=sc.nextInt(); int m1=sc.nextInt(); float s=sc.nextFloat(); double q=0.0;//需初始化 if(n==1) { if(s<=90) q=m1*10000*0.01; else if(s>90&&s<=144) q=m1*10000*0.015; else if(s>144) q=m1*10000*0.03;//注意单位是万元,要乘以10000 } else q=m1*10000*0.03; double y=m*0.0005*10000; double j=3.0*s; float c=1.36f*s;//? System.out.print(q+" "+y+" "+j+" "+c);
该代码用了三个else,两个if,一个else 复杂度有点大。
平均一个函数包括的语句数目较多,应将判断部分和计算部分单独做一个方法
第六题:7-6 学号识别
类图:

耦合度、圈复杂度:

Statments(有效语句):27行
Percent Branch Statements(分支语句比例):29.6
Maximum Complexity(该类中最复杂函数的复杂度):9
由Kiviat Graph图可知:该代码的Avg Complexity(平均复杂度)和Avg Stmts/Method(平均一个函数包括的语句数目)超过范围
Scanner sc=new Scanner(System.in); String num=sc.nextLine();//输入一串数组 String nian,yuan,ban,xue; //输入一串字符 /*输入:是什么 *处理:算法或数据处理过程 *输出:在什么情况下输出什么 */ int i=0; while(i<num.length()) i++; if(i!=8) { System.out.print("Wrong Format"); } else { nian=num.substring(0,2); yuan=num.substring(2,4); ban=num.substring(4,6); xue=num.substring(6,8); if(yuan.equals("01")) { System.out.print("入学年份:20"+nian+"年\n"+"学院:材料学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n"); } else if(yuan.equals("02")) { System.out.print("入学年份:20"+nian+"年\n"+"学院:机械学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n"); } else if(yuan.equals("03")) { System.out.print("入学年份:20"+nian+"年\n"+"学院:外国语学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n"); } else if(yuan.equals("20")) { System.out.print("入学年份:20"+nian+"年\n"+"学院:软件学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n"); } else System.out.print("Wrong Format");
这题的代码if 、else if用了太多。测试点:正常值测试 还完全没过,代码有漏洞(不知道在哪呜呜呜)。估计是复杂度太大了,代码很容易出错,有Bug。
第二次作业:
第一题:7-1 菜单计价程序-1
类图:

耦合度、圈复杂度:

Statments(有效语句):169行
Percent Branch Statements(分支语句比例):21.7
Maximum Complexity(该类中最复杂函数的复杂度):7
由Kiviat Graph图可知:该代码平均复杂度和最复杂函数的复杂度都在绿色范围内,表述良好。
简述:
由Kiviat Graph图知:Dish.getPrice()、Main.main()、Menu.searthDush()、Order.addRecord()、Order.getTotalPrice()、Record.getPrice()的复杂度分别是4、2、3、5、2、1。复杂度都不大。各项指标都在绿色范围内。
但是这个题真的搞了太久,搞了两天才搞好,当时真是想死的心都有了。。。
按照老师提供的类、类的属性和方法。这个题目分为:Main类、Dish类(菜品类)、Menu类(菜谱类)、Record类(点菜记录类)、Order类(订单类)。
该题需要先对Dish类中的name、unit_price赋初值。点菜时输入菜名和份额,调用searchDish()方法进行判断是否有该菜,若没有该菜,则输出菜名+does not exist。若有,则调用addRecord()方法添加点菜记录。最后以end结束,并调用Order类里面的getTotalPrice()方法计算出订单的总费用。
这个题目写好久主要是因为刚开始用面向对象的思想,创建了几个类,和类的属性和方法。不知道怎么传参,包括类的传参、this、构造方法怎么用。
当时有一个问题就是在menu的DIsh对象里面赋了初值,但是在Order类里面点菜时调用Order类里面的getTotalPrice()方法、Record类里面的getPrice()方法和Dish里面的getPrice(int portion)方法进行计算价格,发现Record数组里面的Dish对象内的unit_price(单价)总是为0。因为我没有把new的menu对象传到Order里面的getTotalPrice()方法中。当时还不知道怎么改,导致我直接在addRecord(String dishName,int portion)中用if来进行判断record里面的Dish对象的unit_price该是多少。
针对这个问题进行优化:
int getTotalPrice(Order order,Menu menu,int dn[]){//计算订单的总价 int j=0,sum=0; Dish d; while(order.records[j]!=null) { d=menu.searthDish(order.records[j].d.name); if(d!=null) order.records[j].d=d; if(dn[j]!=1) sum+=order.records[j].getPrice(); j++; } return sum; }
如果没有用if else来判断unit_price该为多少,而是直接传Menu对象,代码的复杂度肯定更低。
第二题:7-2 菜单计价程序-2
类图:

耦合度、圈复杂度:

Statments(有效语句):136行
Percent Branch Statements(分支语句比例):19.1
Maximum Complexity(该类中最复杂函数的复杂度):15
由Kiviat Graph图可知:Average Complexity为4,表示良好。但是Maximum Complexity(该类中最复杂函数的复杂度)为15,超过了范围。
简述:
这个系列第二题的类和第一题的一样,还是Main类、Dish类(菜品类)、Menu类(菜谱类)、Record类(点菜记录类)、Order类(订单类)。
但是在点菜的基础上新加了一个添加菜品信息的方法:Dish addDish(String dishName,int unit_price)//添加一道菜品信息,和删除点菜记录的方法delARecordByOrderNum(int orderNum)//根据序号删除一条记录 、findRecordByNum(int orderNum)//根据序号查找一条记录。
在第一题的基础上,需要输入你所添加的菜品信息,然后进行点菜、删除。所以,这里需要在主方法里面判断到底什么时候判断时进行添加菜品信息,还是开始点菜、删除。这个题的最复杂函数为Main,复杂度为15.主要就是因为要判断什么时候开始调用不同的功能。我的判断方法就是通过判断该行字符串的这个字符串是否为“1”。如果为1,那么就开始了点菜,如果end就结束。如果又有一个“1”,那么就代表开始进行删除,如果end就结束。而且当时还没有用split(分割的方法),这样判断肯定有bug。(可能就是因为这个判断的方法导致我有几个测试点没过啊啊啊!!后面的多条订单的测试点都没过)。更好的方法就是使用split()方法将空格分割出去,其他的内容直接加在定义的数组里面,然后判断第几个是否为字符‘1’,‘delete’。
针对这个问题进行优化:
data=sc.nextLine()
arr=data.split(" ");
while(true) { if(data.equals("end")) break; if(arr.length==2&&!arr[1].equals("delete"))//如果长度等于二,则添加菜品 { while(arr.length==2&&!arr[1].equals("delete")) { ...... data=sc.nextLine(); if(data.equals("end")) break; // brr=data.split(" "); // if(brr.length==2&&brr[1].equals("delete")) // break; arr=data.split(" "); } } if(data.equals("end")) break; else//如果不等于二,则开始点菜 { ....... data=sc.nextLine(); if(data.equals("end")) break; arr=data.split(" "); } if(arr.length==4&&!arr[0].equals("table"))//如果第一个不是table,则为点菜记录 {
......
} data=sc.nextLine(); if(data.equals("end")) break; // brr=data.split(" "); // if(b) // break; arr=data.split(" "); } } if(data.equals("end")) break; if(arr[1].equals("delete")) { int y=0; while(arr[1].equals("delete")) { ...... } } if(data.equals("end")) break; }
除了实现第一题所要的功能,还要再增加删除功能,还要计录所点的每个菜的点菜号、菜名和份数,计算每个菜的价钱并输出。删除的菜也要计算,如果存在所删的对象,则订单总价减去该菜的价钱,如果没有,则输出delete error;。还有一个麻烦的点就是,应该在判断是否存在该菜、是否有该删除对象和计算每个菜的菜价之后就直接输出相应的“菜名+does not exist”、“delete error”和“序号+菜名+费用”。而不是如果存在不存在删除对象就返回0,存在就返回1.这样很玛烦。
第三题:7-3 jmu-java-日期类的基本使用
类图:

耦合度、圈复杂度:

Statments(有效语句):283行
Percent Branch Statements(分支语句比例):26.9
Maximum Complexity(该类中最复杂函数的复杂度):59(救命!!,Main里面用了太多if else )
由Kiviat Graph图可知:Average Complexity为10,Max Complexity是59,(太高了吧,唉)。除了这两个,Avg Depth(平均函数深度),Avg Stmts/Merhod(平均每个方法中的语句)也都超标了。(我太难了。。。。)
简述:
这个题目的Main复杂度太高了,主要是因为用了太多的if else来判断,这题要判定是否为合法日期、判断该年是否闰年、判定日期是否合法且结束日期是否早于起始日期。再判断是否合法时,还得先判断是否为闰年,因为闰年二月份有29天,平年只有8天。没想到的是,判断日期还要判断输入的格式是否为"YYYY-MM-dd"(这个是属是没注意到。。。)还是要学习如何降低复杂度(均有效且合法,且不是闰年、均有效且合法,第一行包含闰年的测试点没过),每个方法中的语句也太多了,差不多快到五六十行了,因为要用到switch语句判断该月份是30天还是31天。但是应该把这个功能单独拿出来,避免重复写。
这个题我用到了Java里面的Calendar、ParseException、SimpleDateFormat、LocalDate、temporal.ChronoUnit和Date类。(要继续探索Java的奥义,真好用)。
第三次作业:
第一题:7-1 菜单计价程序-3
类图:

耦合度、圈复杂度:

Statments(有效语句):266行
Percent Branch Statements(分支语句比例):22.9
Maximum Complexity(该类中最复杂函数的复杂度):44(太难过了)
由Kiviat Graph图可知:Average Complexity为7.18(也比较高了),Max Complexity是44,(比那个判断日期的稍微低一点点哈哈哈)。Tablesearchrq()复杂度为11。Avg Depth(平均函数深度),Avg Stmts/Merhod(平均每个方法中的语句)都严重超标啊!绷不住了。
简述:
这个题目在前两个题目的基础上又加上了桌号,和一个桌给另一个桌点菜的功能。增加了一个Table类,Table类中又包含了Order。由于一个餐馆不止一个桌,所以先new一个Table类的数组,记录每桌的信息。这次老师并没有给我们提供Table类,而是要我们自己设计类。在able类当中,还要判断是否点菜时间再营业时间范围内,所以Table类当中加上了一个searchrq()的方法。用于判断是否在营业时间范围内,是否是周末点菜。如果是在营业范围内,则返回discount的值
为8或6或10。如果不是则返回0。DIsh类:String name;//菜品名称int unit_price; //单价int getPrice(int portion,int num)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)如果portion=1,unit_price*num;如果portion=2返回1.5*unit_price*num;如果都不是,unit_price*2*num;Menu类:Dish[] dishs//菜品数组,保存所有菜品信息Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。使用循环,在DIsh数组里面查找是否有该菜,如果有,那么返回找到的Dish对象,如果没有,则返回空。Dish addDish(String dishName,int unit_price)//添加一道菜品信息,返回添加的Dish对象。Record 类i:orderNum;//序号\Dish d//菜品\num;//份数portion;//份额(1/2/3代表小/中/大份)\int getPrice(){//计价,计算本条记录的价格\创建一个变量接受d调用getPrice方法返回的值。Order类Record[] records//保存订单上每一道的记录,discount//折口,int getTotalPrice(Order order,Menu menu,int dn[]){使用遍历对record数组进行判断是否有该菜,如果有,则赋上record里面的dish对象,如果dn[i]等于1,则为删除的菜,不计入总价,否则计入总价。Record addRecord(int orderNum,String dishName,int portion,int num) :创建Record对象,接受相应信息。int delARecordByOrderNum(int orderNum){//根据序号删除一条记录,对record数组进行遍历,如果有该点菜序号,则返回1,否则返回0,int数组dn接受。void findRecordByNum(int orderNum,Menu menu){//根据序号查找一条记录,对record数组进行遍历,如果有该菜,则赋上record数组里面的dish对象,如果找到了该点菜信息的序号,则调用record类的getPrice方法,输出序号+菜名+该菜价格。Table类:Order order//每个桌都有一个订单,tnum;//桌序号,int[] dn//记录要删除的,dn1//记录要删除的个数,String[] hbook=new String[20];//记录代点的对想和被带点的对象。rq//日期,sj//时间,int[] r=new int[20];double searchrq()//判断是否在营业范围内,以及discount该为多少。返回discount。
Main类:用split方法对输入的信息进行分割,加上循环进行输入,判断是哪个阶段(不过这个流程if else语句用了太多,需要改进)。然后在遍历所有的桌类,对每桌的信息进行输出。
但这其实很麻烦,不必对每桌判断或计算出的信息进行存储后在输出,一个改为直接按题目要求的信息进行判断和计算,然后按顺序输出即可。
其次就是有很多地方都用到了如果存在该菜,那么d就为空,这个应该单独写成一个方法就可以直接调用,不必重复写。
在判断日期,时间的时候,分为先判断是星期几,再判断在不在营业时间范围内,这两个方法可以分开写,这样就避免方法中语句太多,实用性不强。
后面的题目:7-2 有重复的数据、7-3 去掉重复的数据、7-4 单词统计与排序、7-5 面向对象编程(封装性)、7-6 GPS测绘中度分秒转换、7-7 判断两个日期的先后,计算间隔天数、周数
前两个题目差不多,都用到了Java里面的List、ArrayList、HasSet、LinkedHashSet类,以及replace方法。
第四题单词统计与排序:Collections.sort(list1,String.CASE_INSENSITIVE_ORDER);//首字母排序忽略大小写,list1.sort(new Sort_length());//长度排序。
第六题分秒转换:注意Java里面double不用%lf,而是%f(真的会谢)。
第七题判断日期:LocalDate类中of()、isAfter()、isBefore()方法,ChronoUnit类中DAYS、WEEKS、MONTHS等方法。
在这里才觉得Java是真的牛!!!
踩坑与心得:
①第三个菜单系列的题目,格式错误了好久啊,最后一天才改过来的。原来不需要用鼠标双击看后面有多少个空格,只需要复制过去照着输出样例的改就可以了。(蠢死了啊蠢死了)
②next()和nextLine()是真的用明白了啊,之前输入的内容和数组里面存储的总是不一样,终于改好了。
next():它会自动地消除有效字符之前的空格,只返回输入的字符,不会得到带空格的字符串。\n\n也就是说如果输入了一串字符,到了有空格的时候就会停止录入,只录入空格前面的东西,空格后面的东西(包括分隔的空格都会保留在缓存区域)\n\n除了空格以外,Tab键和Enter键都被视为分隔符(结束符)。
nextLine():它返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的。\n\n也就是说输入一串字符,它就可以接受所有字符包括空格,但是遇到回车Enter就会停止录入,只录入前面的东西。
还有一个注意的点就是nextLine这个L要大写而不是小写!!!
③7-4房产税费计算2022这个题特别注意数据的单位:房款(整数/单位万元)、评估价(整数/单位万元)、房屋面积(浮点数/单位平方米)。在计算价格的时候记得乘上10000。
if(n==1) { if(s<=90) q=m1*0.01; else if(s>90&&s<=144) q=m1*0.015; else if(s>144) q=m1*0.03;//注意单位是万元,要乘以10000 } else q=m1*0.03; double y=m*0.0005;
改正后:
if(n==1) { if(s<=90) q=m1*10000*0.01; else if(s>90&&s<=144) q=m1*10000*0.015; else if(s>144) q=m1*10000*0.03;//注意单位是万元,要乘以10000 } else q=m1*10000*0.03; double y=m*0.0005*10000;
④在使用substring(int a,int b)方法的时候,注意是前开后闭,下标为a的取到,下标为b的不会取到。
⑤7-7判断三角形类型的时候如果是
if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a)
System.out.print("Right-angled triangle");
测试点等腰直角三角形就会过不了,应该为if((a*a+b*b-c*c<0.1)||(a*a+c*c-b*b<0.1)||(b*b+c*c-a*a<0.1)),虽然不知道为啥。。。

else if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a) System.out.print("Right-angled triangle");
改进后:
if((a*a+b*b-c*c<0.1)||(a*a+c*c-b*b<0.1)||(b*b+c*c-a*a<0.1)) System.out.print("Right-angled triangle");
注意题目要求三条边的取值范围均为[1,200],而我写的是if(a<1||b<1||c<1||a>200||b>200||c>200),少了等号啊啊!难怪非三角形测试点一直过不了,居然刚刚才发现,绷不住了。

if(a<1||b<1||c<1||a>200||b>200||c>200)
{
System.out.print("Wrong Format");
return;
}
改正后:
if(a<=1||b<=1||c<=1||a>=200||b>=200||c>=200) { System.out.print("Wrong Format"); return; }
⑥7-1 菜单计价程序-1,没有传Menu menu,吃大亏。
优化后:
int getTotalPrice(Order order,Menu menu,int dn[]){//计算订单的总价 int j=0,sum=0; Dish d; while(order.records[j]!=null) { d=menu.searthDish(order.records[j].d.name); if(d!=null) order.records[j].d=d; if(dn[j]!=1) sum+=order.records[j].getPrice(); j++; } return sum; }
在运行时,有好多menu.dish[i].d为null,Order.record[j].record为null,Record里面的record也new了,Dish里面的dish也new了,明明new了menu和order但还是为null。这是因为虽然new了menu和order和Dish、Order里面的也都new了,但是数组没有new。应该加上new Dish[100],new Record[100]。

Dish[] dishs;//菜品数组,保存所有菜品信息 Record[] records;//保存订单上每一道的记录
改正后:
Dish[] dishs=new Dish[10];//菜品数组,保存所有菜品信息 Record[] records=new Record[100];//保存订单上每一道的记录
⑦7-2 菜单计价程序-2,没有用split方法进行分割,吃大亏。
不需要先判断点的菜是否存在,删除的是否存在,再标记为返回0则存在,返回1则不存在。最后再遍历order里面的record里面的int型数组是0,还是1来判断是否输出delete error,does not exist。直接按照样例给出判断后输出相应的结果即可。
⑧7-3 jmu-java-日期类的基本使用,计算相差了多少个月的时候,要算上年份相差了多少,而不是只看月份的数值相差了多少。
还有要注意的是,题目明确提出:第一行输入一个日期字符串,格式为"YYYY-MM-dd"。所以还要判断输入的格式是否正确,这里就要使用substring(int a,int b);方法和equals(" ")方法。
优化后:
else if(riqi.y.length()==10) { String f2=riqi.y.substring(0,1); String f3=riqi.y.substring(1,2); String f4=riqi.y.substring(2,3); String f5=riqi.y.substring(3,4); String f=riqi.y.substring(4,5); String f6=riqi.y.substring(5,6); String f7=riqi.y.substring(6,7); String f1=riqi.y.substring(7,8); String f8=riqi.y.substring(8,9); String f9=riqi.y.substring(9,10); if(!f.equals("-")||!f1.equals("-")) x=0; if(f2.equals("-")||f3.equals("-")||f4.equals("-")||f5.equals("-")||f6.equals("-")||f7.equals("-")||f8.equals("-")||f9.equals("-")) x1=0; ...... }
⑨7-4 小明走格子,这个题目是真的,我不理解。。。必须要用StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));这个类会让数据读取的更快。

优化后:
StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); sc.nextToken(); int t = (int)sc.nval; int i,j,g=0; ......
for(i=0;i<t;i++) { sc.nextToken(); b[i] = (int)sc.nval; if(g < b[i]) g = b[i]; }
主要困难以及改进建议:
主要困难:就是写菜单系列的题目的时候,不确定类的设计是否正确,合不合适,还有就是有的测试点总是过不了,方法太复杂,有点乱,思路不清晰。
改进建议:
①每个类之间的耦合度太强,要尝试着降低耦合度。
②方法里面的语句太多,没有将功能分开,实用性不强。复杂度也太强,需要改进,例如if else,可以进行优化表达式:针对if、else判断的处理,如果之后没有处理,则在if中直接返回,else无需使用;提炼函数:将可以组织独立起来的代码放进一个独立函数中,并使用可以解释函数用法的函数名。简化代码[合并条件式、使用更简洁的表达]:将当前算法重构成更简洁清晰的算法。减少认知复杂度:如果大量使用if-else语句可以考虑用switch代替;考虑使用return和break替换标记变量,提高可读性。工具类替换逻辑判断:使用已有的工具类判断。判空等操作可以使用工具类,减少&&和||的判断使用。
复杂度太大,导致代码漏洞太多,很多测试点过不了。代码也写得太乱。
③有时候就是想到还有什么功能没写就加上什么。应该提前设计好思路,看好所有的题目要求,先设计大概,再设计方法。
④还有就是代码没有照着老师给的注释格式进行注释。应该按照老师的要求来。
总结:
这三次题目主要分为三类。
第一类就是菜单系列:该系列是真正用到了Java面向对象的思想,用到了Dish类、Record类、Order类、Table类、Menu类。这个系列的题目
第二类就是日期判断系列:这个系列都是要使用Date、LocalDate中的计算相差多少天,多少月,多少年、和split分割符判断是否格式相同。
第三个系列就是数据计算:这里就要注意类型转换和数据输出要求是小数点后几位,掌握Math类里面的部分方法,注意Java里面double是%f。
第四个系列就是字符串的处理:用到了List、ArrayList、LinkedHashSet、Collections.sort();//首字母排序、list1.sort(new Sort_length());//长度排序,和replace方法。
学到了:面向对象的基础思想,类与类之间的关系和用法,构造方法的用法,Java里面各种类的用法,如何再类的方法上传参。学到了封装,即把彼此相关数据和操作包围起来,抽象成为一个对象,变量和函数就有了归属,想要访问对象的数据只能通过已定义的接口。
学习及研究的地方:如何降低圈复杂度,如何降低耦合度,如何增加代码的实用性,然后将方法的语句变少,学会使用面向对象的思想。
对教师、课程、作业、实验、课上课下组织方式的改进建议:课程上每次都布置课堂任务及时练习很好,但是希望可以讲解一下下一次大作业的思路(菜单系列),也可以把同学问的较多的问题再课堂上讲解一下,也可以分享在群上。
浙公网安备 33010602011771号