題目集1~3的總結
- (1)前言
- (2)設計與分析
- (3)總結
一、前言
題目集01的考察比較基礎難度偏低,幾十行程式碼就差不多可以完成,只要C語言的基礎較好,題目集01就不會有太大的問題,考察了java的輸入輸出及對String類的一些簡單方法;題目集02的難度一般,題量較少,主要考察的知識點是對Sring類的charAt(i)的使用,如何精準的提取字串的內容;題目集03的題目難度較高(對於我現在的水平),考察了對類的設計,加強了對類的認識。
二、設計與分析
題目集01:
7-2 串列埠字元解析
RS232是串列埠常用的通訊協議,在非同步通訊模式下,串列埠可以一次傳送5~8位資料,收發雙方之間沒有資料傳送時線路維持高電平,相當於接收方持續收到資料“1”(稱為空閒位),傳送方有資料傳送時,會在有效資料(5~8位,具體位數由通訊雙方提前設定)前加上1位起始位“0”,在有效資料之後加上1位可選的奇偶校驗位和1位結束位“1”。請編寫程式,模擬串列埠接收處理程式,注:假定有效資料是8位,奇偶校驗位採用奇校驗。
程式碼:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String str = new String(); str = in.nextLine(); boolean isNull=false; int num = 0,num1=0,t=0; for(int i = 0;i<str.length();i++){if(str.charAt(i)=='1'){ isNull=true; }else if(str.charAt(i)=='0') { t=i; isNull=false; break; } } for(int i=t;i<str.length();i++){ if(str.length()<11||isNull){ System.out.println("null data");//若資料不足11位或者輸入資料全1沒有起始位,則輸出"null data", break; }else if(str.charAt(i)=='0'&&(i+10)<str.length()){ for(int j=i+1;j<=(i+9);j++){ if(str.charAt(j)=='1') { num1++; } } if(num1%2!=0&&str.charAt(10+i)!='1'){ num++; System.out.println(num+":validate error");//若資料結束符和奇偶校驗均不合格,輸出“validate error”。 }else if(num1%2==0&&str.charAt(10+i)=='1'){ num++; System.out.println(num+":parity check error");//若某個資料奇偶校驗錯誤,則輸出“parity check error”。 }else if(num1%2==0&&str.charAt(10+i)!='1'){ num++; System.out.println(num+":validate error");//若某個資料的結束符不為1,則輸出“validate error”。 }else if(str.charAt(i)=='0'&&str.charAt(10+i)=='1'&&num1%2!=0){ num++; System.out.println(num+":"+str.subSequence(i+1,i+9)); } num1=0; i=i+10; } } } }
踩坑心得:
- 兩組資料,一個為正常值,一個結束符不為1,不要判斷完第一組資料的結束符就忘記判斷接下來的資料的結束符是否為1。
- 三組資料,含結束符錯誤資料、奇偶校驗錯誤資料和正常值,兩種錯誤與正確的資料的情況的判斷,對於這3種情況的正確輸出,考慮要全面,把多種情況列出來分析,再把重複的情況排除,學會除錯(debug),用debug不斷測試,找出未能正確輸出的程式碼,dubug可以幫助你快速的找出問題,而不是沒有方向地修改程式碼。
- 本題題目表面看上去比較複雜,因為存在一些新的概念,要去讀懂題目的意思,弄懂奇偶校驗位,不要太著急直接寫程式碼,同時要注意輸出格式,如空格,回車等,以免浪費更多時間。
- 注意String的長度,設定訪問限制,不要超過字串的最大長度,這是經常容易出現的語法問題
改進建議:先判斷首和尾是否符合要求,可以使用String的subSequence方法提取8位資料。
題目集03:
7-1 用類解一元二次方程式
定義一個代表一元二次方程ax2+bx+c=0的類QuadraticEquation,其屬性為三個係數a、b、c(均為私有屬性),類中定義的方法參考main方法中的程式碼。
程式碼:
import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner input = new Scanner(System.in); double a = Double.parseDouble(input.next()); double b = Double.parseDouble(input.next()); double c = Double.parseDouble(input.next()); if(a == 0){ System.out.println("Wrong Format"); System.exit(0); } //create a QuadraticEquation object QuadraticEquation equation = new QuadraticEquation(a, b, c); //get value of b * b - 4 * a * c double discriminant = equation.getDiscriminant(); System.out.println("a=" + equation.getA() + ",b=" + equation.getB() + ",c=" + equation.getC()+":"); if (discriminant < 0) { System.out.println("The equation has no roots."); } else if (discriminant == 0){ System.out.println("The root is " + String.format("%.2f", equation.getRoot1())); } else // (discriminant >= 0){ System.out.println("The roots are " + String.format("%.2f", equation.getRoot1()) + " and " + String.format("%.2f", equation.getRoot2())); } } } class QuadraticEquation{ private double a,b,c; public QuadraticEquation() { super(); // TODO 自動生成的建構函式存根 } //your code public double getRoot2() { // TODO 自動生成的方法存根 return (-b-Math.sqrt(getDiscriminant()))/(2*a); } public double getRoot1() { // TODO 自動生成的方法存根 return (-b+Math.sqrt(getDiscriminant()))/(2*a); } public double getC() { // TODO 自動生成的方法存根 return c; } public double getB() { // TODO 自動生成的方法存根 return b; } public double getA() { // TODO 自動生成的方法存根 return a; } public double getDiscriminant() { // TODO 自動生成的方法存根 return b*b-4*a*c; } public QuadraticEquation(double a, double b, double c) { // TODO 自動生成的建構函式存根 this.a=a; this.b=b; this.c=c; } }
踩坑心得:
- 本題需要注意輸出格式:兩行和保留兩位小數。
- 先判斷x2的係數是否為0,再判斷Δ的大小,最後再根據題目要求輸出。
7-2 日期類設計
參考題目集二中和日期相關的程式,設計一個類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”格式返回日期值
應用程式共測試三個功能:
- 求下n天
- 求前n天
- 求兩個日期相差的天數
有三種輸入方式(以輸入的第一個數字劃分[1,3]):
- 1 year month day n //測試輸入日期的下n天
- 2 year month day n //測試輸入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //測試兩個日期之間相差的天數
程式碼:
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 = 0; private int month = 0; private int day = 0; public DateUtil() { super(); // TODO 自動生成的建構函式存根 } public DateUtil(int year, int month, int day) { // TODO 自動生成的建構函式存根 this.day=day; this.month=month; this.year=year; } 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 checkInputValidity()//檢測輸入的年、月、日是否合法 { boolean check=true; if(year>2020||year<1820||month>12||month<1||day>31||day<1) { return false; } else { if(isLeapYear(year)) { if(month==2&&day>29) { check=false; } else if((month==4||month==6||month==9||month==11)&&day>30) { check=false; } } else { if(month==2&&day>28) { check=false; } else if((month==4||month==6||month==9||month==11)&&day>30) { check=false; } } } return check; } public boolean isLeapYear(int year){//判斷year是否為閏年 boolean isLeapYear=false; if((year % 4 == 0&&year % 100 != 0)||year % 400 ==0){ isLeapYear = true; } else { isLeapYear = false; } return isLeapYear; } public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期 { while(n>0) { if(isLeapYear(year)){ if(month==2){ if(n<=29-day) { day+=n; n=0; } else { month++; n-=30-day; day=1; } } else if(month==1||month==3||month==5||month==7||month==8||month==10) { if(n<=31-day) { day+=n; n=0; } else { month++; n-=32-day; day=1; } } else if(month==12) { if(n<=31-day) { day+=n; n=0; } else { month=1; year++; n-=32-day; day=1; } } else if(month==4||month==6||month==9||month==11) { if(n<=30-day) { day+=n; n=0; } else { n-=31-day; day=1; month++; } } } else { if(month==2){ if(n<=28-day) { day+=n; n=0; } else { month++; n-=29-day; day=1; } } else if(month==1||month==3||month==5||month==7||month==8||month==10) { if(n<=31-day) { day+=n; n=0; } else { month++; n-=32-day; day=1; } } else if(month==12) { if(n<=31-day) { day+=n; n=0; } else { month=1; year++; n-=32-day; day=1; } } else if(month==4||month==6||month==9||month==11) { if(n<=30-day) { day+=n; n=0; } else { n-=31-day; day=1; month++; } } } } DateUtil date = new DateUtil(year, month, day); return date; } public DateUtil getPreviousNDays(int n){//取得year-month-day的前n天日期 while(n>0) { if(isLeapYear(year)) { if(month==1) { if(n>=day) { n-=day; day=31; month=12; year--; } else { day-=n; n=0; } } else if(month==5||month==7||month==10||month==12) { if(n>=day) { n-=day; day=30; month--; } else { day-=n; n=0; } } else if(month==8) { if(n>=day) { n-=day; day=31; month--; } else { day-=n; n=0; } } else if(month==3) { if(n>=day) { n-=day; day=29; month--; } else { day-=n; n=0; } } else if(month==2||month==4||month==6||month==9||month==11) { if(n>=day) { n-=day; day=31; month--; } else { day-=n; n=0; } } } else { if(month==1) { if(n>=day) { n-=day; day=31; month=12; year--; } else { day-=n; n=0; } } else if(month==5||month==7||month==10||month==12) { if(n>=day) { n-=day; day=30; month--; } else { day-=n; n=0; } } else if(month==8) { if(n>=day) { n-=day; day=31; month--; } else { day-=n; n=0; } } else if(month==3) { if(n>=day) { n-=day; day=28; month--; } else { day-=n; n=0; } } else if(month==2||month==4||month==6||month==9||month==11) { if(n>=day) { n-=day; day=31; month--; } else { day-=n; n=0; } } } } DateUtil date = new DateUtil(year, month, day); return date; } public boolean compareDates(DateUtil date){//比較當前日期與date的大小(先後) if(year>date.year) return true; else if(year<date.year) return false; else if(year==date.year&&month>date.month) return true; else if(year==date.year&&month<date.month) return false; else if(year==date.year&&month==date.month&&day>date.day) return true; else if(year==date.year&&month==date.month&&day<date.day) return false; else return false; } public boolean equalTwoDates(DateUtil date){//判斷兩個日期是否相等 if(year==date.year&&month==date.month&&day==date.day) return true; else return false; } public int getDaysofDates(DateUtil date){//求當前日期與date之間相差的天數 if(equalTwoDates(date)) return 0; else { if(compareDates(date)) { return getDays()-date.getDays(); } else { return date.getDays()-getDays(); } } } public int getDays() { int days = 0; int i=0; month--; if(isLeapYear(year)){ while(month>0){ if(month==1||month==3||month==5||month==7||month==8||month==10){ month--; days+=31; } else if(month==4||month==6||month==9||month==11){ month--; days+=30; } else if(month==2){ month--; days+=29; } } days+=day; } else{ while(month>0){ if(month==1||month==3||month==5||month==7||month==8||month==10){ month--; days+=31; } else if(month==4||month==6||month==9||month==11){ month--; days+=30; } else if(month==2){ month--; days+=28; } } days+=day; } for(i=1;i<year;i++){ if(i%4==0&&i%100!=0||i%400==0) { days+=366;} else days+=365; } return days; } public String showDate(){//以“year-month-day”格式返回日期值 String str=year+"-"+month+"-"+day; return str; } }View Code
踩坑心得:
- 注意邊界值的測試,年,月,日。
- 平年和閏年的的區別,可以二月的天數。
- 加天數,月不變化,月變化,年不變化,年變化的情況,考慮全面。
- 判斷天數是否小於每一個月的最大天數。
- 選項3可以用兩組時間到同一年同一個月同一天的數值再相減,以求出兩組時間相差的天數。
改進建議:
- 可以用陣列存每個月的天數。(若為閏年,二月多加一天)
- 用迴圈來實現選項1和2,減少重複程式碼的出現。
- 可以建三個類實現三個選項的功能。
7-3 日期問題面向物件設計(聚合一)
參考題目7-2的要求,設計如下幾個類:DateUtil、Year、Month、Day,其中年、月、日的取值範圍依然為:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 設計類圖如下:
程式碼:
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自動生成的方法存根 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.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.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(fromDate.getDaysofDates(toDate)); } else { System.out.println("Wrong Format"); System.exit(0); } } else{ System.out.println("Wrong Format"); System.exit(0); } } } class Day{ private Month month=new Month(); private int value; private int [] mon_maxnum= {31,28,31,30,31,30,31,31,30,31,30,31}; public Day() { super(); // TODO 自動生成的建構函式存根 } public Day(int yearValue,int monthValue,int dayValue) { } public Month getMonth() { return month; } public void setMonth(Month month) { this.month = month; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public boolean validate() { if((value>31||value<1)&&(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10||month.getValue()==12)|| (value>30||value<1)&&(month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11) ||(value>29||value<1)&&month.getValue()==2&&month.getYear().isLeapYear() ||(value>28||value<1)&&month.getValue()==2&&!month.getYear().isLeapYear()) return false; else return true; } public void dayIncrement() { if(value<mon_maxnum[month.getValue()-1]&&month.getValue()-1!=1) value++; else if(month.getYear().isLeapYear()&&month.getValue()-1==1&&value<29) { value++; } else if(!month.getYear().isLeapYear()&&month.getValue()-1==1&&value<28) { value++; } else { month.monthIncrement(); resetMin(); } } public void dayReduction() { if(value>1) value--; else { month.monthReduction(); resetMax(); } } public void resetMin() { value=1; } public void resetMax() { if(month.getYear().isLeapYear()&&month.getValue()==2) value=29; else value=mon_maxnum[month.getValue()-1]; } } class Month{ private Year year=new Year(); private int value; public Month() { super(); // TODO 自動生成的建構函式存根 } public Month(int yearValue,int monthValue) { super(); this.value=monthValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } public void monthIncrement() { if(value<12) value++; else { resetMin(); year.yearIncrement(); } } public void monthReduction() { if(value>1) value--; else { resetMax(); year.yearReduction(); } } public void resetMin() { value=1; } public void resetMax() { value=12; } public boolean validate() { if(value>12|value<1) return false; else return true; } } class Year{ public Year() { super(); // TODO 自動生成的建構函式存根 } private int value; public Year(int value) { super(); this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public boolean isLeapYear() { if((value % 4 == 0&&value % 100 != 0)||value % 400 ==0) return true; else return false; } public boolean validate() { if(value>2050||value<1900) return false; else return true; } public void yearIncrement() { value++; } public void yearReduction() { value--; } } class DateUtil{ private Day day = new Day(); public DateUtil() { super(); // TODO 自動生成的建構函式存根 } public DateUtil(int y, int m, int d) { super(); day.setValue(d); day.getMonth().setValue(m); day.getMonth().getYear().setValue(y); } public Day getDay() { return day; } public void setDay(Day day) { this.day = day; } public boolean checkInputValidity() { return (day.getMonth().getYear().validate()&&day.validate()&&day.getMonth().validate()); } public boolean compareDates(DateUtil date) { if(day.getMonth().getYear().getValue()>date.day.getMonth().getYear().getValue()) return true; else if(day.getMonth().getYear().getValue()<date.day.getMonth().getYear().getValue()) return false; else if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&day.getMonth().getValue()>date.day.getMonth().getValue()) return true; else if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&day.getMonth().getValue()<date.day.getMonth().getValue()) return false; else if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&day.getMonth().getValue()==date.day.getMonth().getValue()&&day.getValue()>date.day.getValue()) return true; else if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&day.getMonth().getValue()==date.day.getMonth().getValue()&&day.getValue()<date.day.getValue()) return false; else return false; } public int getDaysofDates(DateUtil date) { int a=getDays(),b=date.getDays(); if(equalTwoDates(date)) return 0; else { if(compareDates(date)) { return getDays()-date.getDays(); } else { return date.getDays()-getDays(); } } } public boolean equalTwoDates(DateUtil date){//判斷兩個日期是否相等 if(day.getMonth().getYear().getValue()==date.day.getMonth().getYear().getValue()&&day.getMonth().getValue()==date.day.getMonth().getValue()&&day.getValue()==date.day.getValue()) return true; else return false; } public String showDate() { String str=day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue(); return str; } public DateUtil getNextNDays(int n){//取得year-month-day的下n天日期 while(n>0) { day.dayIncrement(); n--; } DateUtil date = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue()); return date; } public DateUtil getPreviousNDays(int n) { while(n>0) { day.dayReduction(); n--; } DateUtil date = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue()); return date; } public int getDays() { int days = 0; int i=0; int m = day.getMonth().getValue()-1; int d; if(day.getMonth().getYear().isLeapYear()){ while(m>0){ if(m==1||m==3||m==5||m==7||m==8||m==10){ m--; days+=31; } else if(m==4||m==6||m==9||m==11){ m--; days+=30; } else if(m==2){ m--; days+=29; } } days+=day.getValue(); } else{ while(m>0){ if(m==1||m==3||m==5||m==7||m==8||m==10){ m--; days+=31; } else if(m==4||m==6||m==9||m==11){ m--; days+=30; } else if(m==2){ m--; days+=28; } } days+=day.getValue(); } for(i=1899;i<day.getMonth().getYear().getValue();i++){ if(i%4==0&&i%100!=0||i%400==0) { days+=366;} else days+=365; } return days; } }View Code
我的類圖:
踩坑心得:
- 分析清楚類圖,弄清不同類之間是如何聯絡的。(“-”代表private,“+‘代表public)
- 注意該題與7-2的年的取值範圍不一樣。
- 先寫classYear ,再寫class Month ,然後再寫class Day ,最後寫class Dateutil。
改進建議:將類與類之間的的組合關係修改為聚合。
7-4 日期問題面向物件設計(聚合二)
參考題目7-3的要求,設計如下幾個類:DateUtil、Year、Month、Day,其中年、月、日的取值範圍依然為:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 設計類圖如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自動生成的方法存根 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().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " 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().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " 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 Day{ private int value; public Day() { super(); // TODO 自動生成的建構函式存根 } public Day(int value) { super(); this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void dayIncrement() { value++; } public void dayReduction() { value--; } public void resetMin() { value=1; } public void resetMax() { } } class Month{ private int value; public Month() { super(); // TODO 自動生成的建構函式存根 } public Month(int value) { super(); this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void monthIncrement() { value++; } public void monthReduction() { value--; } public void resetMin() { value=1; } public void resetMax() { value=12; } public boolean validate() { if(value>12||value<1) return false; else return true; } } class Year{ public Year() { super(); // TODO 自動生成的建構函式存根 } private int value; public Year(int value) { super(); this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public boolean isLeapYear() { if((value % 4 == 0&&value % 100 != 0)||value % 400 ==0) return true; else return false; } public boolean validate() { if(value>2020||value<1820) return false; else return true; } public void yearIncrement() { value++; } public void yearReduction() { value--; } } class DateUtil{ private Day day = new Day(); private Year year=new Year(); private Month month=new Month(); private int [] mon_maxnum= {31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil() { super(); // TODO 自動生成的建構函式存根 } public DateUtil(int y, int m, int d) { super(); year.setValue(y); month.setValue(m); day.setValue(d); } public Day getDay() { return day; } public void setDay(Day day) { this.day = day; } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } public Month getMonth() { return month; } public void setMonth(Month month) { this.month = month; } public boolean checkInputValidity() {//檢測輸入的年、月、日是否合法 boolean check=true; if(year.getValue()>2020||year.getValue()<1820||!month.validate()||day.getValue()>31||day.getValue()<1) { return false; } else { if(year.isLeapYear()) { if(month.getValue()==2&&day.getValue()>29) { check=false; } else if((month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11)&&day.getValue()>30) { check=false; } } else { if(month.getValue()==2&&day.getValue()>28) { check=false; } else if((month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11)&&day.getValue()>30) { check=false; } } } return check; } public DateUtil getNextNDays(int n) {//取得year-month-day的下n天日期 while(n>0) { if(year.isLeapYear()){ if(month.getValue()==2){ if(n<=29-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { month.setValue(month.getValue()+1); n-=30-day.getValue(); day.setValue(1); } } else if(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10) { if(n<=31-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { month.setValue(month.getValue()+1); n-=32-day.getValue(); day.setValue(1); } } else if(month.getValue()==12) { if(n<=31-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { month.setValue(1); year.setValue(year.getValue()+1); n-=32-day.getValue(); day.setValue(1); } } else if(month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11) { if(n<=30-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { n-=31-day.getValue(); day.setValue(1); month.setValue(month.getValue()+1); } } } else { if(month.getValue()==2){ if(n<=28-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { month.setValue(month.getValue()+1); n-=29-day.getValue(); day.setValue(1); } } else if(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10) { if(n<=31-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { month.setValue(month.getValue()+1); n-=32-day.getValue(); day.setValue(1); } } else if(month.getValue()==12) { if(n<=31-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { month.setValue(1); year.setValue(year.getValue()+1); n-=32-day.getValue(); day.setValue(1); } } else if(month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11) { if(n<=30-day.getValue()) { day.setValue(day.getValue()+n); n=0; } else { n-=31-day.getValue(); day.setValue(1); month.setValue(month.getValue()+1); } } } } DateUtil date = new DateUtil(year.getValue(), month.getValue(), day.getValue()); return date; } public DateUtil getPreviousNDays(int n) {//取得year-month-day的前n天日期 while(n>0) { if(year.isLeapYear()) { if(month.getValue()==1) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(31); month.setValue(12); year.setValue(year.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==5||month.getValue()==7||month.getValue()==10||month.getValue()==12) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(30); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==8) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(31); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==3) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(29); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==2||month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(31); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } } else { if(month.getValue()==1) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(31); month.setValue(12); year.setValue(year.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==5||month.getValue()==7||month.getValue()==10||month.getValue()==12) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(30); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==8) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(31); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==3) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(28); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } else if(month.getValue()==2||month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11) { if(n>=day.getValue()) { n-=day.getValue(); day.setValue(31); month.setValue(month.getValue()-1); } else { day.setValue(day.getValue()-n); n=0; } } } } DateUtil date = new DateUtil(year.getValue(), month.getValue(), day.getValue()); return date; } public boolean compareDates(DateUtil date) {//比較當前日期與date的大小(先後) if(year.getValue()>date.year.getValue()) return true; else if(year.getValue()<date.year.getValue()) return false; else if(year.getValue()==date.year.getValue()&&month.getValue()>date.month.getValue()) return true; else if(year.getValue()==date.year.getValue()&&month.getValue()<date.month.getValue()) return false; else if(year.getValue()==date.year.getValue()&&month.getValue()==date.month.getValue()&&day.getValue()>date.day.getValue()) return true; else if(year.getValue()==date.year.getValue()&&month.getValue()==date.month.getValue()&&day.getValue()<date.day.getValue()) return false; else return false; } public boolean equalTwoDates(DateUtil date){//判斷兩個日期是否相等 if(year.getValue()==date.year.getValue()&&month.getValue()==date.month.getValue()&&day.getValue()==date.day.getValue()) return true; else return false; } public int getDaysofDates(DateUtil date){//求當前日期與date之間相差的天數 if(compareDates(date)) return getDays()-date.getDays(); else return date.getDays()-getDays(); } private int getDays() { int days = 0; int i=0; month.setValue(month.getValue()-1); if(year.isLeapYear()){ while(month.getValue()>0){ if(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10){ month.setValue(month.getValue()-1); days+=31; } else if(month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11){ month.setValue(month.getValue()-1); days+=30; } else if(month.getValue()==2){ month.setValue(month.getValue()-1); days+=29; } } days+=day.getValue(); } else{ while(month.getValue()>0){ if(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10){ month.setValue(month.getValue()-1); days+=31; } else if(month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11){ month.setValue(month.getValue()-1); days+=30; } else if(month.getValue()==2){ month.setValue(month.getValue()-1); days+=28; } } days+=day.getValue(); } for(i=1;i<year.getValue();i++){ if(i%4==0&&i%100!=0||i%400==0) { days+=366;} else days+=365; } return days; } public String showDate(){//以“year-month-day”格式返回日期值 String str=year.getValue()+"-"+month.getValue()+"-"+day.getValue(); return str; } }View Code
我的類圖:
踩坑心得:
- 與題目集037-3不同,以class Dtaeutil為中心,將class Year,class Month,class Day聚合起來。
- 所有類(除主類)與class Dateutil 聯絡,再與主類聯絡。
三、總結:
- 做題前看清題目意思和題目的輸出格式要求。
- 掌握了一些String類的常用方法,可以做到提取某幾位的字面量。
- 對類的設計掌握不是很好,例如題目集03的7-3,題目要求是聚合關係的類圖,而我自己寫的程式碼生成的類圖卻是組合的關係,同時在完成題目集03所用時間較長。
- 題目集02、03的程式碼幾乎沒有面向物件的思維,多數是c語言風格的程式碼,總想著在一個類裡面解決問題,可以構建多個類實現單一職責原則,做到低耦合,邏輯性更強,需要加強這方面的思維。
- 題目集03的7-2的程式碼中,部分程式碼重複出現,導致程式碼行數很多,寫完程式碼後需要檢查一下,把重複的程式碼糅合在一起。
- 掌握基本的語法規則,加強面向物件的思維。
- 做完題目集03時的思路不是特別清晰,完成時較吃力,需要重新覆盤,釐清思路。