一.前言
总体来说,前三次作业的题量对我来说可能比较大,尤其是对于我这个初学者来说。在看到第一次作业发布时,我承认我是有些害怕我写不完的,但好在第一次的难度不算很高,不过我还是没能拿到满分,第一次作业主要让我熟悉了一些Java的基本语法,也对java的结构有了一定的掌握。其中的难点我认为是在字符串这方面,相较于一般数据较为复杂,且含有比较多的方法来处理相关问题,其中最难的题目应该是GPS数据处理,我最后并没有想到方法来解决。第二次作业题量上少了一些,相应的难度有所上升,题目涉及到了方法的使用,但难度并不大,使用得当之后写起来也很轻松,也是难得的拿了满分,相应的难点也就是方法的使用了。第三次作业题量最少,但难度很高,对我来说是个挑战。第三次作业涉及到了类的使用,又是新的东西。类的使用比方法要稍微复杂一些,又是数据输入又是引用又是方法的使用和返回,结构上有些复杂,比较容易出错,尤其是日期类的设计最是麻烦,需要考虑的东西比较多。
二.设计与分析
1.第一次作业
第一次主要就是对java语法的考察了,难度大一些的就是跟字符串相关的了,毕竟和字符串相关的内容有些多且复杂。
7-5 去掉重复的字符
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner input= new Scanner(System.in); String s1=input.nextLine(); int n; n=s1.length(); char[] m2=new char[n]; char[] m1= s1.toCharArray(); int i=0,j=0,a=0; for(i=0;i<n;i++){ for(j=0;j<n;j++){ if(m1[i]==m1[j]){ break; } } if (j == i) { m2[a++] = m1[i];} } for(i=0;i<a;i++) System.out.print(m2[i]); } }
这个题目就是对字符串的一个基本考察了,在刚开始学习字符串时卡了我相当长的一段时间,最后处理出来了。感觉我使用的方法复杂了,将字符串输入到数组中来进行处理,没有重复的字符就直接输入第二个数组,有重复就只将第一个出现的输入第二个数组,应该有更简便的方法。
不过通过这道题让我对字符串的使用和一些方法有了一定的认知,后面出现其他有用到字符串的也较快就解决了。
2.第二次作业
第二次作业就开始使用方法了,这确实是一种方便的多的手段,能避免很多错误,也方便编写和检查。
7-9 求下一天
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31]
import java.util.Scanner; 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(); int Year; int Month; int Day; if(checkInputValidity(year,month,day)){ Year= nextDate(year,month,day)/10000; Month=nextDate(year,month,day)/100-(nextDate(year,month,day)/1000)*10; Day=nextDate(year,month,day)-(nextDate(year,month,day)/100)*100; System.out.print("Next date is:"+Year+"-"+Month+"-"+Day); } else { System.out.print("Wrong Format"); } } public static boolean isLeapYear(int year){ boolean a= true; if((year%4==0&&year%100!=0)||year%400==0){ a=true; } else{ a=false; } return a; } public static boolean checkInputValidity(int year,int month,int day){ boolean a=true; if(year<1820||year>2020||month<1||month>12){ a=false; } else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ if(day<1||day>31){ a=false; } else if(month==4||month==6||month==9||month==11){ if(day<1||day>30){ a=false; } } } if(isLeapYear(year)){ if(month==2&&(day<1||day>29)){ a=false; } } else { if(month==2&&(day<1||day>28)){ a=false; } } return a; } public static int nextDate(int year, int month, int day) { int newYear = year; int newMonth = month; int newDay = day; if (month == 12 && day == 31) { newYear = year + 1; newMonth = 1; newDay = 1; } else if (isLeapYear(year) && month == 2 && day == 29) { newMonth = 3; newDay = 1; } else if (!isLeapYear(year) && month == 2 && day == 28) { newMonth = 3; newDay = 1; } else if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 30) { newMonth = month + 1; newDay = 1; } else if (day == 31) { newMonth = month + 1; newDay = 1; } else { newDay = day + 1; } return newYear * 10000 + newMonth * 100 + newDay; } }
上图为判断日期时使用的一些方法,对输入的日期进行判断,判断其是否为闰年,是一年中的哪个月以及是否是这个月的最后一天或一年的最后一天,并将判断结果传递给运算部分,使其能够计算出日期的下一天。
本题涉及到了方法的调用和递归,对方法的相关用法考察较为全面,让我对方法的使用有了一定的掌握 。
3.第三次作业
这也是前三次作业中难度最大的一次,涉及到了类的使用,在难度上就比前两次要高很多,而且更复杂,十几行代码解决的问题是不会出现了,基本都快上百行才能解决一道问题。
类的使用是其中最大的难点,也是这次作业考察的重点。
7-3 定义日期类
在定义日期类中,我将日期的判断方法和计算放在了类Date中,对日期进行判断,并设置了多个方法来针对日期的各种情况,具体情况与上题类似。
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner input= new Scanner(System.in); Date date=new Date(); int year; int month; int day; date.year=input.nextInt(); date.month=input.nextInt(); date.day=input.nextInt(); year=date.year; month=date.month; day=date.month; int Year; int Month; int Day; Year= date.getnextday()/10000; Month=date.getnextday()/100-Year*100; Day=date.getnextday()-(date.getnextday()/100)*100; if(Year>2000){ System.out.print("Date Format is Wrong"); } else if(date.getcheck()) { System.out.print("Next day is:"+Year+"-"+Month+"-"+Day); } else if (!date.getcheck()){ System.out.print("Date Format is Wrong"); } } } class Date{ int year; int month; int day; public int getyear(int year){ return year; } public void setyear() { this.year=year; } public int getmonth(int month){ return month; } public void setmonth() { this.month=month; } public int getday(int day){ return day; } public void setday() { this.day=day; } public boolean isLeapYear(int year) { boolean a= true; if((year%4==0&&year%100!=0)||year%400==0){ a=true; } else{ a=false; } return a; } public boolean checkInputValidity(int year,int month,int day){ boolean a=true; if(year<1900||year>2000||month<1||month>12){ a=false; } else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ if(day<1||day>31){ a=false; } } else if(month==4||month==6||month==9||month==11){ if(day<1||day>30){ a=false; } } if(isLeapYear(year)){ if(month==2&&(day<1||day>29)){ a=false; } } else { if(month==2&&(day<1||day>28)){ a=false; } } return a; } public int nextDate(int year, int month, int day) { int newYear = year; int newMonth = month; int newDay = day; if (month == 12 && day == 31) { newYear = year + 1; newMonth = 1; newDay = 1; } else if (isLeapYear(year) && month == 2 && day == 29) { newMonth = 3; newDay = 1; } else if (!isLeapYear(year) && month == 2 && day == 28) { newMonth = 3; newDay = 1; } else if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 30) { newMonth = month + 1; newDay = 1; } else if (day == 31) { newMonth = month + 1; newDay = 1; } else { newDay = day + 1; } return newYear * 10000 + newMonth * 100 + newDay; } public int getnextday() { return nextDate(year, month, day); } public boolean getcheck(){ return checkInputValidity(year,month,day); } }
这题给我的感觉是在对类的基本用法掌握之后的一些进阶考察,让我对类的更多的用法有了初步掌握。
7-4 日期类设计
参考题目3和日期相关的程序,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:
public boolean checkInputValidity();//检测输入的年、月、日是否合法
public boolean isLeapYear(int year);//判断year是否为闰年
public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期
public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期
public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后)
public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等
public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数
public String showDate();//以“year-month-day”格式返回日期值
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; public DateUtil(int year,int month,int day){ this.year=year; this.month=month; this.day=day; } public boolean checkInputValidity(){ if(year<1820||year>2020||month<1||month>12||day<1||day>getMonthMaxDays()){ return false; } return true; } public String showDate() { return String.format("%04d-%02d-%02d", year, month, day); } public int getYear() { return year; } public int getMonth() { return month; } public int getDay() { return day; } public int getMonthMaxDays() { if(isLeapYear()) { if(month==2) { day=29; } } if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) { day=31; } if(month==4||month==6||month==9||month==11) { day=30; } return day; } public boolean isLeapYear(){ boolean a= true; if((year%4==0&&year%100!=0)||year%400==0){ a=true; } else{ a=false; } return a; } public DateUtil getNextNDays(int n) { int totalDays = day + n; int maxDays = getMonthMaxDays(); while (totalDays > maxDays) { totalDays=totalDays-maxDays; month++; if (month > 12) { month = 1; year++; } maxDays = getMonthMaxDays(); } return new DateUtil(year, month, totalDays); } public DateUtil getPreviousNDays(int n) { int totalDays = day - n; int maxDays = getMonthMaxDays(); while (totalDays < 1) { month--; if (month<1){ month=12; year--; } maxDays = getMonthMaxDays(); totalDays=totalDays+maxDays; } return new DateUtil(year,month,totalDays); } public int getDaysofDates(DateUtil date) { if (date.year<year||date.year==year&&(date.month<month||date.month==month&&date.day<day)){ return date.getDaysofDates(this); } int days = 0; while (year<date.year||month<date.month||day<date.day){ days++; day++; if (day > getMonthMaxDays()) { day = 1; month++; } if (month > 12) { month = 1; year++; } } return days; } }
这题的难度相较于上题有大提升,主要就是计算量变大了,而且情况复杂的多。日期的判断方法还是和上一题一样。
对于日期的计算还多了一个要判断的点,求前几天还是求后几天。这是一个需要注意的点,所以需要加上几个方法来区分不同情况。
1、求下n天
个人感觉就是求下一天的升级版,在求下一天的基础上加上了一个循环,同时对年份和月份进行判断,保证输出的日期正确。
2.求前n天
这就相当于一个新东西了,比较判断方法与下n天不一样,计算还是老老实实挨个减。
3.求相差天数
这是一个相当麻烦的东西,我并没有想到什么简单的方法,我先比较哪个日期更靠前,然后从靠前一直加到靠后的日期,同时记录加了几天。
三.踩坑心得
在完成题目的过程中我也犯过许多错误,就比如我在将字符串输入数组时并没有输入进去,导致数组一直是空的,结果也是空的。
后来我对改变了一下输入方式使用“tochar”将字符串输入,代码为“char[] m1= s1.toCharArray();”。
一开始并不知道有这个办法,是一直在书上找,最后在与字符串相关的内容中找到了这个。
还有在第二次作业中判断三角形形状时,对于等腰直角三角形的判断出了错。
后面才想到我没法输入根号2,所以最后采用了近似值的方法。
做第三次作业时有个判断月末的地方出了问题,导致我每次运行都能出来三十几号的天数,后面一步步排查发现上面判断天数的地方少了一个括号,就直接导致他不判断是不是月末了,直接加天数,最后就出现了32号这种奇怪的东西。
改正之后就对了,{}这个东西还是一个一个的写比较好,不然找起来是真的难。
最后命名真的很重要,乱起名字真的会让人搞不懂是什么意思。
四.改进建议
对日期类的改进我有些想法,也许我可以将所以的判断都写成方法,然后用的时候直接去调用,这样编写的时候也会节省时间,也避免了被识别成垃圾代码的情况。
第三次的7-4我的代码还有错误,很多地方的判断和运算并不合理,导致了我的结果和正确结果有一定的误差,可以对其进行修正,使其能够运算出正常结果。
改进的地方也许还有很多。
五.总结
前三次作业主要就是让我掌握Java的基本语法,以及类和方法的使用,这些都是Java中最基础的,掌握了这些我才能在以后的学习中正常的完成,我认为自己在类的使用方法上还不是很熟练,应该用更多的时间去练习一下,还有一个很重要的问题,我打字时总会不自觉的放慢速度,这个问题必须要解决一下。
对于课堂上的内容我觉得还是很有用的,虽然和我现在做作业的内容联系不大,但毕竟是以后吃饭用的,我应该让自己尽力去能理解课堂内容。
至于作业,只要处于正常范围内就还好,题量和难度只要让我有时间去完成就可以接受了,但我还是希望能有时间去休息的。