一、作业概述
前三次作业都是对java基础知识的训练,大都是面向过程的,其中包括了关于对象的声明与创建、数值数据类型和操作、输入与输出、选择结构、循环结构、对字符串的操作、数组、方法的定义与调用、类的定义、作用域、类与类和方法与方法之间的关系、以上知识的综合运用等众多知识,可谓是一次大杂烩。这三次的作业题量都比较多,但难度并不大,代码量最多就几十行,只有最后一、两题较难。这对我这个初学者来说十分友好,能让我很快熟悉java独特的语法规则和整体排布。下面是对这三次作业的详细分析。
二、源码分析
第1次作业:这次作业主要是对选择循环结构、数据的查重与去重、表达式构建的考察,难度简单。
7-2 根据BIM值输出,在这我因为体重与身高范围没限定好,导致无效边界值测定错误,因此选择结构条件得设置好。yi
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 double BMI = 0; 7 double weight = input.nextDouble(); 8 double height = input.nextDouble(); 9 if (weight < 0 || height <0) { 10 System.out.print("input out of range"); 11 } 12 else { 13 BMI = weight / (height * height); 14 if(BMI < 18.5) 15 System.out.print("thin"); 16 if(BMI >= 18.5 && BMI <24) 17 System.out.print("fit"); 18 if(BMI >= 24 && BMI <28) 19 System.out.print("overweight"); 20 if(BMI >= 28) 21 System.out.print("fat"); 22 } 23 } 24 }

7-4 根据重量求邮费
这题只需使用选择结构就可完成,我一开始没有将体重的全部情况考虑到,导致非零返回,同时引起了答案错误。因此,在写代码时要考虑操作的所有情况,防止丢三落四。同时我也学到了如何将数据四舍五入,只要先将数据加上0.5,再整体用int强制转化符就能实现,对数据类型的设置要恰当,否则误差会较大。
修改前
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 int weight = input.nextInt(); 7 double money = 0; 8 if(weight >= 1 || weight < 20) 9 money = 12.0 + (weight - 1) * 2.0; 10 if(weight >= 20 || weight < 60) 11 money = 39.0 + (weight - 20) * 1.9; 12 if(weight >= 60) 13 money = 115.0 + (weight - 60) * 1.3; 14 System.out.print((int)(money + 0.5)); 15 } 16 }

修改后
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 double weight = input.nextDouble(); 7 double money = 0; 8 if(weight > 0 && weight < 20) 9 money = 12.0 + (weight - 1.0) * 2.0; 10 else if(weight >= 20 && weight < 60) 11 money = 39.0 + (weight - 20.0) * 1.9; 12 else if(weight >= 60) 13 money = 115.0 + (weight - 60.0) * 1.3; 14 15 System.out.print((int)(money+0.5)); 16 } 17 }
第2次作业:这次作业仍然考察的是选择循环结构,但难度升高了一些。
7-3 计算房产税
在一开始没考虑到房屋面积一定得大于零,因此写代码时一定要进行判断输入数据是否合法这一步,确保程序逻辑无误。否则就会出错.
修改前
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 int a = input.nextInt(); 7 int b = input.nextInt(); 8 int c = input.nextInt(); 9 double d = input.nextDouble(); 10 double price1 = 0; 11 if(a == 1) { 12 13 if(d>0&&d <= 90) 14 price1 = c * 0.01; 15 else if(d <= 144) 16 price1 = c * 0.015; 17 else 18 price1 = c * 0.03; 19 } 20 else 21 price1 = c * 0.03; 22 System.out.printf("%.1f %.1f %.1f %.1f", price1*10000.0, b*0.0005*10000, d*3, d*1.36); 23 } 24 }

修改后
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 int a = input.nextInt(); 7 int b = input.nextInt(); 8 int c = input.nextInt(); 9 double d = input.nextDouble(); 10 double price1 = 0; 11 if(d>=0){ 12 if(a == 1) { 13 14 if(d <= 90) 15 price1 = c * 0.01; 16 else if(d <= 144) 17 price1 = c * 0.015; 18 else if(d>144) 19 price1 = c * 0.03; 20 } 21 else 22 price1 = c * 0.03; 23 } 24 System.out.print((float)(price1*10000.0)+" "+(float)(b*0.0005*10000)+" "+(float)(d*3)+" "+(float)(d*1.36)); 25 } 26 }
7-5 学号识别
这题一开始我是将每条选择语句单独成立,没有关联,但题目的意思是要层层深入判断与限定,所以应该用条件语句的嵌套,嵌套中又有平行条件。写代码时最好先想好运行时的逻辑判断,哪个先,哪个后,还是平行的,可以画个流程图辅助。
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 String str = input.next(); 7 int i = 0; 8 9 int n = str.length(); 10 char a[] = new char[n]; 11 for(i=0;i<n;i++) 12 a[i]=str.charAt(i); 13 if(n==8) { 14 15 System.out.println("入学年份:20"+a[0]+a[1]+"年"); 16 17 if(str.substring(2,4).equals("01")) 18 System.out.println("学院: 材料学院"); 19 20 if(str.substring(2,4).equals("02")) 21 System.out.println("学院: 机械学院"); 22 if(str.substring(2,4).equals("03")) 23 System.out.println("学院: 外语学院"); 24 if(str.substring(2,4).equals("20")) 25 System.out.println("学院: 软件学院"); 26 System.out.println("班级: "+a[4]+a[5]); 27 System.out.println("学号: "+a[6]+a[7]); 28 } 29 else 30 System.out.print("Wrong Format"); 31 } 32 }

1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 String str = input.next(); 7 int i = 0; 8 int t = 0; 9 int n = str.length(); 10 if(n==8) { 11 12 if(str.substring(2,4).equals("01")) { 13 System.out.println("入学年份:20"+str.charAt(0)+str.charAt(1)+"年"); 14 System.out.println("学院:材料学院"); 15 } 16 else if(str.substring(2,4).equals("02")) { 17 System.out.println("入学年份:20"+str.charAt(0)+str.charAt(1)+"年"); 18 System.out.println("学院:机械学院"); 19 } 20 else if(str.substring(2,4).equals("03")) { 21 System.out.println("入学年份:20"+str.charAt(0)+str.charAt(1)+"年"); 22 System.out.println("学院:外语学院"); 23 } 24 else if(str.substring(2,4).equals("20")) { 25 System.out.println("入学年份:20"+str.charAt(0)+str.charAt(1)+"年"); 26 System.out.println("学院:软件学院"); 27 } 28 else{ 29 t=1; 30 System.out.print("Wrong Format"); 31 } 32 if(t==0){ 33 System.out.println("班级:"+str.charAt(4)+str.charAt(5)); 34 System.out.print("学号:"+str.charAt(6)+str.charAt(7)); 35 } 36 } 37 else 38 System.out.print("Wrong Format"); 39 } 40 }
第3次作业:这次作业都是对类的运用。创建一个类来完成某些相关操作,其中包括类的属性、创建对象、数据域操作、参数传递等。
7-3 这题要求下一天,题目并不难,整个源码就两个类,一个Main,一个Date类。因为需要每个月的最大天数,所以用数组来对应每个月的天数,这样就能直接调用,更加方便。这道题考验的是逻辑能力。不仅要考虑每个月不同的天数,还要对闰年进行判定以及二月份在平年闰年中天数也不同。虽然首次代码的边界值测定都通过了,但对月份条件的约束是错漏百出,导致多个地方有逻辑错误。之后我直接用出错的月份来测试错误点,很快就知道是方法中的第7、8行出了问题,仔细一看,原来是我马虎了,在跨月份时天直接用的是输入的数据,而不是为1号,从而出错。就是这么一个极小的错误,就导致了多个地方出错,使我认识到代码的严谨。在这题中,我又学到了一个方法,那就是在知道哪个点出错的情况下,直接用具体数据运行一下就那直观地清楚是哪个方法、哪个条件或哪个循环有问题,这种方法十分有效,能节省很多时间。我也学到了一个新的数据类型boolean型,这是c语言所没有的。首次运用了eclipse的调试工具,发现它确实挺好用的。它能跟踪代码的每一步,实时显示各个参数的值,让我清楚了解代码的运行过程,并发现逻辑错误,也是节约时间,提高效率的一大利器。


修改前:
1 public static void getNextDate() { 2 if(!checkInputValidity(year, month, day)) 3 System.out.print("Date Format is Wrong"); 4 else { 5 if(day < mon_maxnum[month] || (isLeapYear(year) && month == 2 && day < 29)) 6 System.out.print("Next day is:" + year + "-" + month + "-" + (day + 1)); 7 if(day == mon_maxnum[month] && month != 12 || isLeapYear(year) && month ==2 && day == 29) 8 System.out.print("Next day is:" + year + "-" + (month + 1) + "-" + day); 9 if(month == 12 && day == 31) 10 System.out.print("Next day is:" + (year + 1) + "-1" + "-1"); 11 }
修改后:
1 public void getNextDate() { 2 if(!checkInputValidity(year, month, day)) 3 System.out.print("Date Format is Wrong"); 4 else { 5 if(day < mon_maxnum[month] || (isLeapYear(year) && month == 2 && day < 29)) 6 System.out.print("Next day is:" + year + "-" + month + "-" + (day + 1)); 7 if(day == mon_maxnum[month] && month != 12 || (isLeapYear(year) && month ==2 && day == 29)) 8 System.out.print("Next day is:" + year + "-" + (month + 1) + "-1"); 9 if(month == 12 && day == 31) 10 System.out.print("Next day is:" + (year + 1) + "-1" + "-1"); 11 }
7-4 这题是一个日期类设计,要求实现的功能有求下n天、前n天、以及求两日期之间的天数。首先7-4一看就是7-3的升级版。三个功能思路还是差不多的,但是考虑的东西变多了。上一题每次最多只会改变年月日中的一个,而这题年月日都可能会变。因此大体上我想按先确定年,再确定月,最后确定日这样一个顺序来实现功能。天数超过一年就对年进行操作,超过一个月就对月进行操作,否则就对天进行操作。其中12月31日与二月最后一天比较特殊,因此我单独拿出来讨论的。其中下n天与前n天方法更是相似,只需对部分数据修改。求两日前之间的天数只要加上开始与结束的条件。用类名作为方法的类型,这时的返回值应是对该类所创建的对象,这样才能把该类的所有属性都传递过去。改进的话只能减少选择语句,要用对象时再进行声明与初始化。

1 public DateUtil getNextNDays(int n) { 2 if(n <= 0){ 3 4 } 5 else{ 6 if(month == 12) { 7 n = n - (31 - day + 1); 8 year = year + 1; 9 month = 1; 10 day = 1; 11 } 12 else { 13 n = n - (mon_maxnum[month] - day + 1); 14 month = month + 1; 15 day = 1; 16 } 17 for(;n > 0;) { 18 if(!isLeapYear(year) && n >= 365) { 19 n = n - 365; 20 year = year + 1; 21 } 22 if(isLeapYear(year) && n >= 366) { 23 n = n - 366; 24 year = year + 1; 25 } 26 if(month == 12) { 27 n = n - (31 - day + 1); 28 year = year + 1; 29 month = 1; 30 day = 1; 31 } 32 if(!isLeapYear(year) && n < 365) { 33 if(n < mon_maxnum[month]) { 34 day = n + 1; 35 n = 0; 36 } 37 if(n >= mon_maxnum[month]) { 38 n = n - mon_maxnum[month]; 39 month = month + 1; 40 } 41 } 42 if(isLeapYear(year) && n < 366) { 43 if(month == 2 && n <29) { 44 day =n + 1; 45 n = 0; 46 } 47 if(month == 2 && n >=29) { 48 n = n - 29; 49 month = 3; 50 day = 1; 51 } 52 if(n < mon_maxnum[month]) { 53 day = n + 1; 54 n = 0; 55 } 56 if(n >=mon_maxnum[month]) { 57 n = n - mon_maxnum[month]; 58 month = month + 1; 59 } 60 } 61 62 } 63 } 64 return new DateUtil(year, month, day); 65 66 }
三、总结
在前三次作业中,我熟悉了java的语言和操作,明白了它与c语言之间的相似和不同。例如,java中的条件循环语句、大部分数据类型和c语言一样;同时java能对字符串直接进行操作,声明的变量必需进行初始化,项目具有各个层次类型等,这些都与c语言不同。在java中许多操作变得更方便了,简化了代码,同时又多了许多。如java的输出有print、printf、println等等,输入有next、nextInt、nextline等等,每种函数都有特定的用法。
当然,在java中也有相应的规范,一开始我并不怎么遵守,后来经老师提醒,一个项目是要给别人看,虽然代码的运行结果都是一样的,但如果不遵守一些规范的话,别人是很难看懂的,而一个项目需要一个团队来共同完成,这就需要团队间的沟通与交流,如果每个人的代码都个性鲜明,那么代码就很难有可读性,团队效率会随之降低。因此,如何将代码写的更规范、更优雅就十分有必要了。在之后写代码时,我会更加注意java的规范的。既然改变不了规则,那就只好适应规则喽。
通过这三次作业,我发现了我的许多不足之处。例如我的逻辑思考能力还有所欠缺,往往把简单题目复杂化,除此之外java语法知识我也只是零零散散地知道,并没系统地学习,java方法的单一职责原则也不是很好的履行,这些都需要我的进一步学习和研究。当然同时我也学会了许多知识,对静态的使用,对字符串的删、查、改操作,一些自带的有用函数,方法、类的定义与使用。同时,我发现少用条件与循环能提高代码的时间效率。对题目要有一定的数据提取能力,哪些是初始数据,那些是中间数据,那些又是最终数据,我认为这对程序员来说是十分重要的。对作业和实验来说,我总体感觉只是题量大,中偏下难度;对与课堂,我认为课上的知识都是实际有用的,干货满满,应该好好深入学习和运用。这样实践与理论相结合的教学对我们来说是非常有用的。