OO第一次总结
前言
这是我的第一篇blog,本学期学习面向对象的程序设计也是我第一次接触到java。由于对java与java语法的不够熟悉,在前几次作业中,闹出一些笑话,也遇到了不少问题。
第一次作业涉及到了顺序结构、选择结构、循环、数组、字符串等知识点,但是较为基础,主要考察是否熟悉java的基本语法。不过7-10 GPS数据处理这道题需要用到许多我没有涉及过的知识,当时我的选择了放弃,现在想起来还是有些懊悔,是一个比较惨痛的教训。
第二次作业涉及的知识点与第一次作业类似,难度有所上升,应该还是帮助我们熟悉java中的语法。其中7-8 判断三角形类型 等腰直角三角形测试的这个测试点卡了我很久,上课听到同学们的讨论才知道是浮点数的误差问题。
第三次作业涉及到了类的定义,getter、setter方法、构造方法的书写,LocalDate类的使用,还需要读类图。虽然这次作业题目量是最少的,但是第一次涉及到类,让我感觉难度突增。不过通过这次作业,我也熟练掌握了怎么构建一个类。
设计与分析
第二次作业
7-9 求下一天
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year=input.nextInt(); int month=input.nextInt(); int day=input.nextInt(); if(checkInputValidity(year,month,day)) nextDate(year,month,day); else System.out.print("Wrong Format"); } public static boolean isLeapYear(int year){ if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } public static boolean checkInputValidity(int year,int month,int day){ if(year>=1820&&year<=2020){ if(month==2) { if(isLeapYear(year)){ if (day >= 1 && day <= 29) return true; else return false; } else{ if (day >= 1 && day <= 28) return true; else return false; } } else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ if(day>=1&&day<=31) return true; else return false; } else{ if(day>=1&&day<=30) return true; else return false; } } else return false; } public static void nextDate(int year,int month,int day){ if(month==12&&day==31){ year+=1; month=1; day=1; } else if(month==2){ if(isLeapYear(year)){ if(day==29){ day=1; month+=1; } else day+=1; } else{ if(day==29){ day=1; month+=1; } else day+=1; } } else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ if(day==31){ day=1; month+=1; } else day+=1; } else{ if(day==30){ day=1; month+=1; } else day+=1; } System.out.print("Next date is:"+year+"-"+month+"-"+day); } }
关于这道题,我是使用判断是否为闰年,再判断月份是否为二月,再判断月份是否为大月,再判断日期是否为该月最后一天。单是打出这一连串的判断,我都能体会到最初我算法设计的有多么不合理,如此复杂的代码导致我甚至一度出现了代码长度过限的问题。但当时,由于没有更好的想法,我也只是简单优化了一下if语句,缩短了一些代码长度,使代码可以提交通过测试点就作罢了。
作业截止后,我与室友交流才发现可以使用数组来存储每个月份的天数,茅塞顿开。通过这道题目我才意识到老师一直强调的沟通交流有多么重要。我也明白了我设计方面存在很大问题,写出的代码质量较低。
第三次作业
7-3 定义日期类
类图

源码
import java.util.*; public class Main { private int year; private int month; private int day; private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public Main(){ } public Main(int year,int month,int day){ this.year=year; this.month=month; this.day=day; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public boolean isLeapYear(int year){ if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } public boolean checkInputValidity(){ if(isLeapYear(year)) mon_maxnum[2]=29; if(year<1900||year>2000||month<1||month>12||day<1||day>mon_maxnum[month]) return false; else return true; } public void getNextDate(){ if(!checkInputValidity()) System.out.println("Date Format is Wrong"); else{ if(month==12&&day==mon_maxnum[month]){ year++; month=1; day=1; } else if(day==mon_maxnum[month]){ month++; day=1; } else day++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } } public static void main(String[] args){ Scanner input=new Scanner(System.in); int year=input.nextInt(); int month=input.nextInt(); int day=input.nextInt(); Main time=new Main(year,month,day); time.getNextDate(); } }
这道题就是第二次作业中 7-9 求下一天 的迭代升级,但是需要定义一个date类,不过老师在题目中给出了类图,帮我们做好了类的设计,为我们提供了一定的思路,比如直接给出了属性mon_maxnum数组,提示我们可以使用数组存放每个月的天数,加上上次作业的经验,写这道题时我感觉较为轻松。
7-4 日期类设计
类图

源码
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year = 0; int month = 0; int day = 0; int choice = input.nextInt(); if (choice == 1) { // test getNextNDays method int m = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } m = input.nextInt(); if (m < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); System.out.println(date.getNextNDays(m).showDate()); } else if (choice == 2) { // test getPreviousNDays method int n = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } n = input.nextInt(); if (n < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print( date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); System.out.println(date.getPreviousNDays(n).showDate()); } else if (choice == 3) { //test getDaysofDates method year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); int anotherYear = Integer.parseInt(input.next()); int anotherMonth = Integer.parseInt(input.next()); int anotherDay = Integer.parseInt(input.next()); DateUtil fromDate = new DateUtil(year, month, day); DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:" + fromDate.getDaysofDates(toDate)); } else { System.out.println("Wrong Format"); System.exit(0); } } else{ System.out.println("Wrong Format"); System.exit(0); } } } class DateUtil { private int year; private int month; private int day; private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil(){ } public DateUtil(int year,int month,int day){ this.day=day; this.month=month; this.year=year; } public int getDay() { return day; } public int getMonth() { return month; } public int getYear() { return year; } public void setDay(int day) { this.day = day; } public void setYear(int year) { this.year = year; } public void setMonth(int month) { this.month = month; } public boolean isLeapYear(int year){ if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } public boolean checkInputValidity(){ if(isLeapYear(year)) mon_maxnum[2]=29; if(year<1820||year>2020||month<1||month>12||day<1||day>mon_maxnum[month]) return false; else return true; } public DateUtil getNextNDays(int n) { int year1=year,month1=month,day1=day; int year_max=365; if(isLeapYear(year1)) { year_max = 366; mon_maxnum[2]=29; } while(n>=year_max){ if(isLeapYear(year1)) { year_max = 366; mon_maxnum[2]=29; } else{ year_max=365; mon_maxnum[2]=28; } n-=year_max; year1++; } while (n>=mon_maxnum[month1]){ n-=mon_maxnum[month1]; month1++; if(month1>12){ year1++; month1-=12; } } if(day1+n>mon_maxnum[month1]){ day1+=n-mon_maxnum[month1]; month1++; } else day1+=n; DateUtil date=new DateUtil(year1,month1,day1); return date; } public DateUtil getPreviousNDays(int n){ int year1=year,month1=month,day1=day; int year_max=365; if(isLeapYear(year1)) mon_maxnum[2]=29; while(n>=year_max){ if(isLeapYear(year1)) mon_maxnum[2]=29; else{ mon_maxnum[2]=28; } n-=year_max; year1--; } while (n>=mon_maxnum[month1]){ n-=mon_maxnum[month1]; month1--; if(month1<1){ year1--; month1=12; } } if(day1-n<=0){ month1--; n-=day1; day1=mon_maxnum[month1]-n; } else day1-=n; if(month1<1){ year1--; month1=12; } DateUtil date=new DateUtil(year1,month1,day1); return date; } public boolean equalTwoDates(DateUtil date){ if(year== date.getYear()&&month== date.getMonth()&&day==date.getDay()) return true; else return false; } public boolean compareDates(DateUtil date){ if(year>date.getYear()) return true; else if(year<date.getYear()) return false; else{ if(month> date.getMonth()) return true; else if (month<date.getMonth()) return false; else{ if(day> date.getMonth()) return true; else return false; } } } public int getDaysofDates(DateUtil date){ int n=0; int year1,year2,month1,month2,day1,day2; if(equalTwoDates(date)) return n; if (compareDates(date)) { year2=year; month2=month; day2=day; day1=date.getDay(); month1=date.getMonth(); year1=date.getYear(); } else{ year1=year; month1=month; day1=day; day2=date.getDay(); month2=date.getMonth(); year2=date.getYear(); } while (year1+1<year2){ if(isLeapYear(year1)&&month1<=2) n+=366; else n+=365; year1++; } while (month1<12){ n+=mon_maxnum[month1]; month1++; } n+=mon_maxnum[12]-day1; int i=1; while (i<month2){ n+=mon_maxnum[i]; i++; } n+=day2; return n; } public String showDate(){ String year1=Integer.toString(year); String month1=Integer.toString(month); String day1=Integer.toString(day); String date=year1+"-"+month1+"-"+day1; return date; } }
这道题作为上一题的迭代升级版,虽然老师也帮我们做完了类的设计,给出了要编写的方法,但还是把我难住了。有着前两次算下一天的经验,算下n天虽然稍微复杂一些,我在思考并于室友讨论后完成了。但是依照相同思路写计算前n天功能出现了一些问题,导致计算日期总会有几天的偏差。并且因为对题目难度没有很好的认识,我仅仅在截止当天的傍晚才开始着手写这道题目,导致最后我没有充足的时间来完善我计算前n天与算两日期相差天数功能的代码,这道题目只拿到了一部分分数,这给我了一个惨痛的教训,我需要端正我对待作业的态度,要认识到java不同于上学期的C语言,即使在截止的当天,只要努努力就能写完。对于以后的java作业,我会更早动手,拿出精益求精的态度来对待。
踩坑心得
部分题目已经在上一部分分析过,这里就不再重复了。
第一次作业
7-1
作为学习java以来做的第一道题目,出现了不少低级问题,例如不知道主方法所在的类必须命名为Main,当时多次提交也完全没发现问题出在哪里。也不知道要用import来引入包。


除开简单的语法错误,我还不清楚java中也可以使用printf输出来保留小数,但是需要注意java中%需要使用%%。
7-2
忽略了题目给出的输入顺序,导致出现错误。


7-3
没有注意到题目给出图片与输出样例格式不同导致错误。
7-5
不知道java中字符串为常量,需要使用StringBuilder才能修改。
7-7
使用了嵌套for循环来寻找数组中重复的元素,出现运行超时的错误。

更换了一种方法后,不会运行超时,但是出现了非零返回的错误,搜索后知道可能是数组越界导致的,发现使用的方法在数组元素过大时很容易出现越界的错误。


第二次作业
7-1
答案错误,但是将double类型数据强制转换为float后答案就正确了。在7-3中也出现了这种问题。


7-8
在两浮点数之间用了==,忽略了浮点数精度导致的误差。





7-9
算法设计过于复杂。
忽视了是否闰年的二月、是否大小月,输入的合法范围不同,需要分开判断。
第三次作业
7-1
不熟悉类的定义,getter、setter、构造方法的书写。忽略了除主类外,其他类不能使用public等修饰符。
改进建议
1.代码不爱写注释,可读性不强,别人、甚至我自己隔一段时间看我代码的时候,总要花上一段时间才知道这段代码的功能是什么。需要培养边写代码边注释的习惯。
2.代码书写不够规范,需要牢记阿里的代码规范。
3.与同学交流不够,很多自己找不出的bug或者思路有误的题目,和同学简单交流一下,很快就能得到解决,还有助于拓展自己的知识面,拓宽思路。
4.对java中的许多类不了解,需要多看教材并在网上学习。
5.对待作业不能再拖延,一发布就要着手去做。
总结
通过这三次作业,我学习到了很多,也发现自己的不足,算是开始入门java了。对老师上课不讲的知识,要多看配套的慕课系统性的学习。自己也要培养好的学习习惯,多掌握一些java知识,为之后基于java的专业课学习打基础。

浙公网安备 33010602011771号