一、题目分析
题目集1:题目集1涉及的知识点主要有①选择结构②字符数组③字符串④数据的输入与输出⑤循环结构,难度较低.
题目集2:题目集二涉及的知识点主要有①选择结构②字符数组③字符串④数据的输入与输出⑤循环结构,主要以字符串为中心。难度中等.
题目集3:题目集3涉及的主要知识点有①选择结构②一维数组③字符串④数据的输入与输出⑤循环结构⑥类和对象⑦方法。难度中等偏上.
二、题目源码分析和遇到的bug
题目集1.6
题目:
学校的学号由8位数字组成,前两位是入学年份(省略了20);第3、4位是学院编号,01代表材料学院,02代表机械学院,03代表外语学院,20代表软件学院;第5、6位是学院内部班级编号,最后两位是班级内部学号。如:18011103,入学年份是2018年,材料学院,11班,03号
8位数字组成的学号。例如:18011103
注意:输入学号不是8位或者学院编号不是01、02、03、20其中之一,属于非法输入
学号每一项的完整说明。例如:
入学年份:2018年
学院:材料学院
班级:11
学号:03
注意:如非法输入,输出“Wrong Format"
源码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input =new Scanner(System.in); String str; str =input.nextLine(); char a[]=str.toCharArray(); if((str.substring(2,4).equals("01")||str.substring(2,4).equals("02")||str.substring(2,4).equals("03")||str.substring(2,4).equals("20"))&&str.length()==8){ System.out.println("入学年份:20"+str.substring(0,2)+"年"); if(str.substring(2,4).equals("01")) System.out.println("学院:材料学院"); if(str.substring(2,4).equals("02")) System.out.println("学院:机械学院"); if(str.substring(2,4).equals("03")) System.out.println("学院:外语学院"); if(str.substring(2,4).equals("20")) System.out.println("学院:软件学院"); System.out.println("班级:"+str.substring(4,6)); System.out.print("学号:"+str.substring(6,8)); } else { System.out.print("Wrong Format"); }
题目关键分析:我的解题思路在于截取关键字符串用于判断再根据判断结果进行输出.
遇到的BUG:在使用str.substring(n,m)方法时不慎导致if语句判断以及后面的数据的输出出错.
解决方案:对str.substring(n,m)方法研究分析,该方法会截取原字符串从下标n开始(包括下表n的字符)到下标m前一个的位置的之间的字符串,导致BUG的原因是我以为还会截取下标m位置的字符.发现之后对源代码进行修改.
题目集1.7
题目:
输入三角形三条边,判断该三角形为什么类型的三角形。
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。
(1)如果输入数据非法,则输出“Wrong Format”;
(2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”;
(3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”;
(3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”;
(5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”;
(6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”;
(7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。
源码如下:
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); double num1 = input.nextDouble(); double num2 = input.nextDouble(); double num3 = input.nextDouble(); double c = num1 * num1; double d = num2 * num2; double e = num3 * num3; if (num1 < 1 || num2 < 1 || num3 < 1 || num1 > 200 || num2 > 200 || num3 > 200) { System.out.println("Wrong Format"); } else { if (num1 == num2 && num1 == num3) { System.out.println("Equilateral triangle"); } else if (num1 + num2 <=num3 || num2 + num3 <=num1 || num1 + num3 <= num2) { System.out.println("Not a triangle"); } else if (num1 == num2 || num2 == num3 || num1 == num3) { if (c+d-e<0.1||c+e-d<0.1||d+e-c<0.1) { System.out.println("Isosceles right-angled triangle"); } else System.out.println("Isosceles triangle"); } else if (c + d == e || d + e == c || c + e == d) { System.out.println("Right-angled triangle"); } else System.out.println("General triangle"); } } }
题目关键分析:首先要根据所学数学知识判断是否能构造出三角形,若能,再根据三条边的长度关系判断是何类型。
遇到的BUG:在判断等腰直角三角形时,用c+d==e||d + e == c || c + e == d作为判断条件导致判断错误。
解决方案:考虑到这是由于精度问题导致的错误,用c+d-e<0.1||c+e-d<0.1||d+e-c<0.1代替c+d==e||d + e == c || c + e == d则可解决上述问题.
题目集3.3(聚合一)
题目:
设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
题目关键分析:对于该题目的解决,重点在于分清楚类图所表示的类间关系,闰年的判断方法,注意数据输出数据的格式要求,输入数据的范围要求,格式要求。难点在于要理清用处理month的类管理处理year的类,用处理day的类再控制处理month的类在间接控制处理year的类,实现一个类管理所有的年月日相关的所有数据。求前n天后n天日期相差的天数,都要注意以下几点情况,1.闰年和平年的二月份天数不同,闰年二月份有29天,而平年有28天,所以要编写条件语句进行区分。2.求后天时要注意12.31到1.1号时除了天数要从31变回1月份也是,求前n天时要注意1.1号到12.31号时进行天数与月数的特殊转换,求日期相差的天数,我使用的算法是判断出更小的日期,用循环再一天一天的往后推直到年月日都与较大的日期相同,并且记录加了多少天,这就是相差的天数,所以我要注意12.31号到1.1月份与年份的归一。
题目集3.4(聚合二)
题目:参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
题目关键分析:对于该题目的解决,重点在于分清楚类图所表示的类间关系,闰年的判断方法,注意数据输出数据的格式要求,输入数据的范围要求,格式要求。难点在于理解类图所表示的类之间的从属关系,monthl类和day类和year类之间并没有明显的关联,他们都与Dateutil类关联,由main类调用Dateutil类来完成功能的实现。求前n天后n天日期相差的天数,都要注意以下几点情况,1.闰年和平年的二月份天数不同,闰年二月份有29天,而平年有28天,所以要编写条件语句进行区分。2.求后天时要注意12.31到1.1号时除了天数要从31变回1月份也是,求前n天时要注意1.1号到12.31号时进行天数与月数的特殊转换,求日期相差的天数,我使用的算法是判断出更小的日期,用循环再一天一天的往后推直到年月日都与较大的日期相同,并且记录加了多少天,这就是相差的天数,所以我要注意12.31号到1.1月份与年份的归一。
聚合一与聚合二之间的比较:
相同之处:两种聚合方式所得到的代码在使用类里面的方法时大同小异,无非就是变量名称的改变。实现的功能也·相同.
不同之处与孰优孰劣:
首先我个人认为聚合二是优于聚合一的,原因有以下几点:
1.聚合一是通过类之间的多重调用实现一个类控制多个类,用month类与year类关联再用day类与month类关联,实现一个类控制多个类,缺点在于,当所需创建的类过多时,各个类之间的关系会变的复杂,导致代码编写困难。而聚合二是将需要的类先创建出来,各个类之间耦合性低,然后创建一个类似于中介的类来调用创建的各个类,这种聚合方法易于他人理解和接受,并且调用关系简单,更为适合这个题目。
2.聚合一在进行代码编写时会导致代码过于繁琐,例如要获取年份,聚合一则要调用getDay().getMonth().getYear().getvalue();二聚合二只需getYear().getvalue();这会加大代码编写出错的概率;
二.学习感悟
经过这七周来的题目联系和课堂积累我学到了以下主要知识点
1.字符串与字符数组的转换.
2.学会创建类和方法并学会用类之间的不同关系解决问题.
3.学会了正则表达式简单使用.
4.学会了设置断点进行调试来发现异常报错如数组越界以及非语法而是逻辑上的错误。
5.学会了有关字符串转化为字符数组、截取字符串......等方法.
三、总结分析
1.关于java,在解决问题中,在实现所需的功能的同时,也要具有面向对象的思维,不能只站在解题者的角度看待问题,而要同时留意使用者可能遇到的问题。
2.编程最重要的的是各种基础知识的积累,要多了解有着各种功能的各种方法和语法,必要时可以看看方法中的源码看看是如何进行编写和运行的,有时这会让你一开始感觉十分棘手的问题迎刃而解,有时这提供了同一种问题的多种解决方法。像题目集4的题目,若是不用正则表达式,就会在刚开始的输入数据判断上下很大功夫,学习了有关正则表达式的相关知识就让其变得相对简单。
3.java的学习实践大于理论,掌握编程在于遇到将理论用于实践,然后遇到各种各样的问题,解决问题后你所收获的远比书上的知识多得多。成功解决问题也是对自己的一种激励,对学习成果的肯定。
4.合理的类间关系可以让代码更加高效、合理、简单。