第二次作业总结

一、前言

  这三次作业主要包括正则表达式的运用以及图形类的继承、多态知识点。

  第四次作业当中的水文校验及处理需要运用到非常多的正则表达式以及对String类的各种方法的运用,计算量非常大,任务繁杂,要注意的细节也很多。日期问题面向对象设计对于类的聚合关系也有了严格要求,同样计算量非常大,但有了各种类图框架,其中的类与类之间的聚合关系就简单了一点。

  第五次作业中的统计Java程序中关键字的出现次数也主要是以正则表达式为主,但较之于水文处理,题量明显减小了不少。且题目中要求用到接口类辅助做题,有了Map接口和正则表达式的使用,使得题目对于字符统计更加简单。这次作业的聚合题和第四次作业差不多,减少了年、月、日类当中各类的含参方法,而是直接使用类之间的聚合关系。

  第六次作业题量虽然多了一点,但大多数都是比较基础的正则匹配,难度很小。图形继承题也比较基础。

 

二、设计与分析

(1)

题目集4(7-2)日期问题面向对象设计(聚合一)

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

 

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数
  1 import java.util.Scanner;
  2 public class Main {
  3     public static void main(String[] args)
  4     {
  5         Scanner input=new Scanner(System.in);
  6         int m=input.nextInt();
  7         int year=input.nextInt();
  8         int month=input.nextInt();
  9         int day=input.nextInt();
 10         int n;
 11         DateUtil time=new DateUtil(year,month,day);
 12         switch(m)
 13         {
 14         case 1://求下n天
 15                 n=input.nextInt();//输入n
 16                 if(!time.checkInputValidity()||n<0){//如果数据不合法
 17                     System.out.println("Wrong Format");
 18                     System.exit(0);
 19                 }
 20                 else
 21                     System.out.println(time.getNextNDays(n).showDate());
 22                 break;
 23             case 2:
 24                 n=input.nextInt();//输入n
 25                 if(!time.checkInputValidity()||n<0){//如果数据不合法
 26                     System.out.println("Wrong Format");
 27                     System.exit(0);
 28                 }
 29                 else
 30                     System.out.println(time.getPreviousNDays(n).showDate());
 31                 break;
 32             case 3:
 33                 int year1,month1,day1;
 34                 year1=input.nextInt();month1= input.nextInt();day1=input.nextInt();//输入第二个年月日
 35                 DateUtil time1=new DateUtil(year1,month1,day1);
 36                 if(!time.checkInputValidity()||!time1.checkInputValidity()){//如果数据不合法
 37                     System.out.println("Wrong Format");
 38                     System.exit(0);
 39                 }
 40                 else
 41                     System.out.println(time.getDaysofDates(time1));
 42                 break;
 43             default:
 44                 System.out.println("Wrong Format");
 45                 break;
 46         }
 47 
 48     }
 49 }
 50 class DateUtil
 51 {
 52     Day day;
 53     public DateUtil()
 54     {
 55 
 56     }
 57     public DateUtil(int yearValue,int monthValue,int dayValue)
 58     {
 59         this.day=new Day(yearValue,monthValue,dayValue);
 60     }
 61 
 62     public Day getDay() {
 63         return day;
 64     }
 65 
 66     public void setDay(Day day) {
 67         this.day = day;
 68     }
 69     public boolean checkInputValidity()
 70     {
 71         return this.getDay().validate()&&this.getDay().getMonth().getYear().validate()&&this.getDay().getMonth().validate();
 72     }
 73     public boolean compareDates(DateUtil date)
 74     {
 75         if(date.getDay().getMonth().getYear().getValue()<this.getDay().getMonth().getYear().getValue())
 76             return false;
 77         else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()<this.getDay().getMonth().getValue())
 78             return false;
 79         else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()&&date.getDay().getValue()<this.getDay().getValue())
 80             return false;
 81         else
 82             return true;
 83     }
 84     public boolean equalTwoDates(DateUtil date)
 85     {
 86         return date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&
 87                 date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()&&date.getDay().getValue()
 88                 ==this.getDay().getValue();
 89     }
 90     public String showDate()
 91     {
 92         return this.getDay().getMonth().getYear().getValue()+"-"
 93                 +this.getDay().getMonth().getValue()+"-"+this.getDay().getValue();
 94     }
 95     public DateUtil getNextNDays(int n)
 96     {
 97         int[] mon_maxnum ={31,28,31,30,31,30,31,31,30,31,30,31};
 98         if(this.getDay().getMonth().getYear().isLeapYear())
 99         {
100             mon_maxnum[1]=29;
101         }
102         int days=0;
103         int i;
104         for(i=this.getDay().getMonth().getValue()+1;i<=12;i++)
105         {
106             days+=mon_maxnum[i-1];
107         }
108         days+=mon_maxnum[(this.getDay().getMonth().getValue())-1]-this.getDay().getValue();
109         int day=0,month=0,year = 0;
110         if(days>n)//剩余天数大于n天
111         {
112             year=this.getDay().getMonth().getYear().getValue();
113             if((mon_maxnum[(this.getDay().getMonth().getValue())-1]-this.getDay().getValue())>=n)//n天后再本月
114             {
115                 month=this.getDay().getMonth().getValue();
116                 day=n+this.getDay().getValue();
117             }
118             else//n天后不再本月
119             {
120                 n=n-(mon_maxnum[this.getDay().getMonth().getValue()-1]-this.getDay().getValue());
121                 month=this.getDay().getMonth().getValue()+1;
122                 i=month;
123                 while(n-mon_maxnum[i-1]>0&&i<=12)
124                 {//找到月
125                     n=n-mon_maxnum[i-1];
126                     month++;
127                     i++;
128                 }
129                 day=n;//找到天
130             }
131         }
132         else//n天后不在今年
133         {
134             n=n-days;
135             year=this.getDay().getMonth().getYear().getValue()+1;
136             int x=365;
137             if(new Year(year).isLeapYear()){
138                 x++;
139             }
140             while(n-x>0){//找到年
141                 n=n-x;
142                 year++;
143                 x=365;
144                 if(new Year(year).isLeapYear())
145                     x++;
146             }
147             i=1;
148             while(n-mon_maxnum[i-1]>0&&i<=12){//找到月
149                 n=n-mon_maxnum[i-1];
150                 i++;
151             }
152             month=i;
153             day=n;//找到天
154         }
155         return new DateUtil(year,month,day);
156     }
157     public DateUtil getPreviousNDays(int n)
158     {
159         int[] mon_maxnum ={31,28,31,30,31,30,31,31,30,31,30,31};
160         if(this.getDay().getMonth().getYear().isLeapYear())
161         {
162             mon_maxnum[1]=29;
163         }
164         int days=0;
165         int i;
166         for(i=this.getDay().getMonth().getValue()+1;i<=12;i++)
167         {
168             days += mon_maxnum[i - 1];
169         }
170         days+=mon_maxnum[(this.getDay().getMonth().getValue())-1]-this.getDay().getValue();
171         int days1=0;
172         days1=365-days;
173         if(this.getDay().getMonth().getYear().isLeapYear())
174         {
175             days1++;
176         }
177         int day=0,month=0,year=0;
178         if(days1>n)//n天前在今年
179         {
180             year=this.getDay().getMonth().getYear().getValue();
181             if(this.getDay().getValue()>n)//n天前在本月
182             {
183                 month=this.getDay().getMonth().getValue();
184                 day=this.getDay().getValue()-n;
185 
186             }
187             else
188             {
189                 n=n-this.getDay().getValue();
190                 month=this.getDay().getMonth().getValue()-1;
191                 i=month;
192                 while(n-mon_maxnum[i-1]>0&&i>=0){//找到月
193                     n=n-mon_maxnum[i-1];
194                     month--;
195                     i--;
196                 }
197                 day=mon_maxnum[i-1]-n;//找到天
198                 /*if(new Year(year).isLeapYear()&&month==2){
199                     day++;
200                 }*/
201             }
202         }
203         else
204         {
205             n=n-days1;
206             year=this.getDay().getMonth().getYear().getValue()-1;
207             int f=365;
208             if(new Year(year).isLeapYear()){
209                 f++;
210             }
211             while(n-f>0){//找到年
212                 n=n-f;
213                 year--;
214                 f=365;
215                 if(new Year(year).isLeapYear())
216                     f++;
217             }
218             i=12;
219             while(n-mon_maxnum[i-1]>0&&i>=0){//找到月
220                 n=n-mon_maxnum[i-1];
221                 i--;
222             }
223             month=i;
224             day=mon_maxnum[i-1]-n;//找到天
225         }
226         return new DateUtil(year, month, day);
227     }
228     public int getDaysofDates(DateUtil date)
229     {
230         DateUtil b1=this;
231         DateUtil b2=date;
232         if(this.equalTwoDates(date)){//如果两天的日期相等
233             return 0;
234         }
235         else if(!this.compareDates(date)){
236             b1=date;
237             b2=this;
238         }
239         int mon_maxnum[]={31,28,31,30,31,30,31,31,30,31,30,31};
240         int i,j,ts=0;
241         for(i=b1.getDay().getMonth().getYear().getValue()+1;i<b2.getDay().getMonth().getYear().getValue();i++){
242             ts=ts+365;
243             if(new Year(i).isLeapYear())
244                 ts++;
245         }
246         if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()==b2.getDay().getMonth().getValue()){//年份相同,月份相同,日不同
247             ts=b2.getDay().getValue()-b1.getDay().getValue();
248         }
249         else if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()!=b2.getDay().getMonth().getValue()){//年份相同,月份不同
250             if(b1.getDay().getMonth().getYear().isLeapYear())
251                 mon_maxnum[1]=29;
252             ts=ts+mon_maxnum[b1.getDay().getMonth().getValue()-1]-b1.getDay().getValue();
253             ts=ts+b2.getDay().getValue();
254             for(j=b1.getDay().getMonth().getValue()+1;j<=b2.getDay().getMonth().getValue()-1;j++)
255                 ts+=mon_maxnum[j-1];
256         }
257         else if(b1.getDay().getMonth().getYear().getValue()!=b2.getDay().getMonth().getYear().getValue()){
258             ts=ts+mon_maxnum[b1.getDay().getMonth().getValue()-1]-b1.getDay().getValue();
259             ts=ts+b2.getDay().getValue();
260             for(j=b1.getDay().getMonth().getValue()+1;j<=12;j++)
261                 ts=ts+mon_maxnum[j-1];
262             for(j=b2.getDay().getMonth().getValue()-1;j>0;j--)
263                 ts=ts+mon_maxnum[j-1];
264             if(b1.getDay().getMonth().getYear().isLeapYear()&&b1.getDay().getMonth().getValue()<=2)
265                 ts++;
266             if(b2.getDay().getMonth().getYear().isLeapYear()&&b2.getDay().getMonth().getValue()>2)
267                 ts++;
268         }
269         return ts;
270     }
271 }
272 
273 /*
274 **天类
275  */
276 
277 class Day
278 {
279     int value;
280     Month month;
281     int[] mon_maxnum ={31,28,31,30,31,30,31,31,30,31,30,31};
282     public Day()
283     {
284 
285     }
286     public Day(int yearValue,int monthValue,int dayValue)
287     {
288         this.value=dayValue;
289         this.month=new Month(yearValue,monthValue);
290     }
291 
292     public int getValue() {
293         return value;
294     }
295 
296     public void setValue(int value) {
297         this.value = value;
298     }
299 
300     public Month getMonth() {
301         return month;
302     }
303 
304     public void setMonth(Month month) {
305         this.month = month;
306     }
307     public void resetMin()
308     {
309         value=1;
310     }
311     public void resetMax()
312     {
313         value=mon_maxnum[month.getValue()-1];
314     }
315     public boolean validate()
316     {
317         if(month.getValue()<1||month.getValue()>12)
318         {
319             return false;
320         }
321         return value>=1&&value<=mon_maxnum[month.getValue()-1];
322     }
323     public void dayIncrement()
324     {
325         value+=1;
326     }
327     public void dayReduction()
328     {
329         value-=1;
330     }
331 }
332 
333 /*
334 **月类
335  */
336 
337 class Month
338 {
339     int value;
340     Year year;
341     public Month()
342     {
343 
344     }
345     public Month(int yearValue,int monthValue)
346     {
347         this.value=monthValue;
348         this.year=new Year(yearValue);
349     }
350 
351     public int getValue() {
352         return value;
353     }
354 
355     public void setValue(int value) {
356         this.value = value;
357     }
358 
359     public Year getYear() {
360         return year;
361     }
362 
363     public void setYear(Year year) {
364         this.year = year;
365     }
366     public void resetMin()
367     {
368         value=1;
369     }
370     public void resetMax()
371     {
372         value=12;
373     }
374     public boolean validate()
375     {
376         return value >= 1 && value <= 12;
377     }
378     public void monthIncrement()
379     {
380         value+=1;
381     }
382     public void monthReduction()
383     {
384         value-=1;
385     }
386 }
387 
388 /*
389 **年类
390 * */
391 
392 class Year{
393     int value;
394     public Year(){
395 
396     }
397     public Year(int value)
398     {
399         this.value=value;
400     }
401 
402     public int getValue() {
403         return value;
404     }
405 
406     public void setValue(int value) {
407         this.value = value;
408     }
409     public boolean isLeapYear()
410     {
411         return (value % 4 == 0 && value % 100 != 0) || (value % 400 == 0);
412     }
413     public boolean validate()
414     {
415         return value >= 1900 && value <= 2050;
416     }
417     public void yearIncrement()
418     {
419         value+=1;
420     }
421     public void yearReduction()
422     {
423         value-=1;
424     }
425 }
View Code

 

 

题目集5(7-4)日期问题面向对象设计(聚合二)

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

 

 

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数 

 

  1 import java.util.Scanner;
  2 public class Main {
  3     public static void main(String[] args)
  4     {
  5         Scanner input=new Scanner(System.in);
  6         int m=input.nextInt();
  7         int year=input.nextInt();
  8         int month=input.nextInt();
  9         int day=input.nextInt();
 10         int n;
 11         DateUtil time=new DateUtil(year,month,day);
 12         switch(m)
 13         {
 14             case 1://求下n天
 15                 n=input.nextInt();//输入n
 16                 if(!time.checkInputValidity()||n<0){//如果数据不合法
 17                     System.out.println("Wrong Format");
 18                     System.exit(0);
 19                 }
 20                 else
 21                     //System.out.println(time.getNextNDays(n).showDate());
 22                     System.out.println(time.showDate()+" next "+n+" days is:"+time.getNextNDays(n).showDate());
 23                 break;
 24             case 2:
 25                 n=input.nextInt();//输入n
 26                 if(!time.checkInputValidity()||n<0){//如果数据不合法
 27                     System.out.println("Wrong Format");
 28                     System.exit(0);
 29                 }
 30                 else
 31                     //System.out.println(time.getPreviousNDays(n).showDate());
 32                     System.out.println(time.showDate()+" previous "+n+" days is:"+time.getPreviousNDays(n).showDate());
 33                 break;
 34             case 3:
 35                 int year1,month1,day1;
 36                 year1=input.nextInt();month1= input.nextInt();day1=input.nextInt();//输入第二个年月日
 37                 DateUtil time1=new DateUtil(year1,month1,day1);
 38                 if(!time.checkInputValidity()||!time1.checkInputValidity()){//如果数据不合法
 39                     System.out.println("Wrong Format");
 40                     System.exit(0);
 41                 }
 42                 else
 43                     //System.out.println(time.getDaysofDates(time1));
 44                     System.out.println("The days between "+time.showDate()+" and "+time1.showDate()+" are:"+time.getDaysofDates(time1));
 45                 break;
 46             default:
 47                 System.out.println("Wrong Format");
 48                 break;
 49         }
 50 
 51     }
 52 }
 53 class DateUtil
 54 {
 55     Day day;
 56     Year year;
 57     Month month;
 58     int[] mon_maxnum ={31,28,31,30,31,30,31,31,30,31,30,31};
 59     public DateUtil()
 60     {
 61     }
 62     public DateUtil(int yearValue,int monthValue,int dayValue)
 63     {
 64         this.day=new Day(dayValue);
 65         this.month=new Month(monthValue);
 66         this.year=new Year(yearValue);
 67     }
 68     public Year getYear()
 69     {
 70         return year;
 71     }
 72 
 73     public void setYear(Year year) {
 74         this.year = year;
 75     }
 76 
 77     public Month getMonth() {
 78         return month;
 79     }
 80 
 81     public void setMonth(Month month) {
 82         this.month = month;
 83     }
 84 
 85     public Day getDay() {
 86         return day;
 87     }
 88     public void setDay(Day day) {
 89         this.day = day;
 90     }
 91     public void setDayMin()
 92     {
 93         this.day.value=1;
 94     }
 95     public void setDayMax()
 96     {
 97         this.day.value=mon_maxnum[month.getValue()-1];
 98     }
 99     public boolean checkInputValidity()
100     {
101         if(this.getYear().isLeapYear())
102         {
103             mon_maxnum[1]=29;
104         }
105          if(this.getMonth().getValue()>12||this.getMonth().getValue()<=0)
106         {
107             return false;
108         }
109         if(day.value>=1&&day.value<=mon_maxnum[month.getValue()-1])
110         {
111             if(this.getMonth().validate()&&this.getYear().validate())
112             {
113                 return true;
114             }
115             else {
116                 return false;
117             }
118         }
119         else
120         {
121             return false;
122         }
123 
124     }
125     public boolean compareDates(DateUtil date)
126     {
127         if(date.getYear().getValue()<this.getYear().getValue())
128             return false;
129         else if(date.getYear().getValue()==this.getYear().getValue()&&date.getMonth().getValue()<this.getDay().getValue())
130             return false;
131         else if(date.getYear().getValue()==this.getYear().getValue()&&date.getMonth().getValue()==this.getMonth().getValue()&&date.getDay().getValue()<this.getDay().getValue())
132             return false;
133         else
134             return true;
135     }
136     public boolean equalTwoDates(DateUtil date)
137     {
138         return date.getYear().getValue()==this.getYear().getValue()&&
139                 date.getMonth().getValue()==this.getMonth().getValue()&&date.getDay().getValue()
140                 ==this.getDay().getValue();
141     }
142     public String showDate()
143     {
144         return this.getYear().getValue()+"-"
145                 +this.getMonth().getValue()+"-"+this.getDay().getValue();
146     }
147     public DateUtil getNextNDays(int n)
148     {
149         int[] mon_maxnum ={31,28,31,30,31,30,31,31,30,31,30,31};
150         if(this.getYear().isLeapYear())
151         {
152             mon_maxnum[1]=29;
153         }
154         int days=0;
155         int i;
156         for(i=this.getMonth().getValue()+1;i<=12;i++)
157         {
158             days+=mon_maxnum[i-1];
159         }
160         days+=mon_maxnum[(this.getMonth().getValue())-1]-this.getDay().getValue();
161         int day=0,month=0,year = 0;
162         if(days>n)//剩余天数大于n天
163         {
164             year=this.getYear().getValue();
165             if((mon_maxnum[(this.getMonth().getValue())-1]-this.getDay().getValue())>=n)//n天后再本月
166             {
167                 month=this.getMonth().getValue();
168                 day=n+this.getDay().getValue();
169             }
170             else//n天后不再本月
171             {
172                 n=n-(mon_maxnum[this.getMonth().getValue()-1]-this.getDay().getValue());
173                 month=this.getMonth().getValue()+1;
174                 i=month;
175                 while(n-mon_maxnum[i-1]>0&&i<=12)
176                 {//找到月
177                     n=n-mon_maxnum[i-1];
178                     month++;
179                     i++;
180                 }
181                 day=n;//找到天
182             }
183         }
184         else//n天后不在今年
185         {
186             n=n-days;
187             year=this.getYear().getValue()+1;
188             int x=365;
189             if(new Year(year).isLeapYear()){
190                 x++;
191             }
192             while(n-x>0){//找到年
193                 n=n-x;
194                 year++;
195                 x=365;
196                 if(new Year(year).isLeapYear())
197                     x++;
198             }
199             i=1;
200             if(new Year(year).isLeapYear())
201             {
202                 mon_maxnum[1]=29;
203             }
204             else
205             {
206                 mon_maxnum[1]=28;
207             }
208             while(n-mon_maxnum[i-1]>0&&i<=12){//找到月
209                 n=n-mon_maxnum[i-1];
210                 i++;
211             }
212             month=i;
213             day=n;//找到天
214         }
215         return new DateUtil(year,month,day);
216     }
217     public DateUtil getPreviousNDays(int n)
218     {
219         int[] mon_maxnum ={31,28,31,30,31,30,31,31,30,31,30,31};
220         if(this.getYear().isLeapYear())
221         {
222             mon_maxnum[1]=29;
223         }
224         int days=0;
225         int i;
226         for(i=this.getMonth().getValue()+1;i<=12;i++)
227         {
228             days += mon_maxnum[i - 1];
229         }
230         days+=mon_maxnum[(this.getMonth().getValue())-1]-this.getDay().getValue();
231         int days1=0;
232         days1=365-days;
233         if(this.getYear().isLeapYear())
234         {
235             days1++;
236         }
237         int day=0,month=0,year=0;
238         if(days1>n)//n天前在今年
239         {
240             year=this.getYear().getValue();
241             if(this.getDay().getValue()>n)//n天前在本月
242             {
243                 month=this.getMonth().getValue();
244                 day=this.getDay().getValue()-n;
245 
246             }
247             else
248             {
249                 n=n-this.getDay().getValue();
250                 month=this.getMonth().getValue()-1;
251                 i=month;
252                 while(n-mon_maxnum[i-1]>0&&i>=0){//找到月
253                     n=n-mon_maxnum[i-1];
254                     month--;
255                     i--;
256                 }
257                 day=mon_maxnum[i-1]-n;//找到天
258                 /*if(new Year(year).isLeapYear()&&month==2){
259                     day++;
260                 }*/
261             }
262         }
263         else
264         {
265             n=n-days1;
266             year=this.getYear().getValue()-1;
267             int f=365;
268             if(new Year(year).isLeapYear()){
269                 f++;
270             }
271             while(n-f>0){//找到年
272                 n=n-f;
273                 year--;
274                 f=365;
275                 if(new Year(year).isLeapYear())
276                     f++;
277             }
278             i=12;
279             while(n-mon_maxnum[i-1]>0&&i>=0){//找到月
280                 n=n-mon_maxnum[i-1];
281                 i--;
282             }
283             month=i;
284             day=mon_maxnum[i-1]-n;//找到天
285         }
286         return new DateUtil(year, month, day);
287     }
288     public int getDaysofDates(DateUtil date)
289     {
290         DateUtil b1=this;
291         DateUtil b2=date;
292         if(this.equalTwoDates(date)){//如果两天的日期相等
293             return 0;
294         }
295         else if(!this.compareDates(date)){
296             b1=date;
297             b2=this;
298         }
299         int mon_maxnum[]={31,28,31,30,31,30,31,31,30,31,30,31};
300         int i,j,ts=0;
301         for(i=b1.getYear().getValue()+1;i<b2.getYear().getValue();i++){
302             ts=ts+365;
303             if(new Year(i).isLeapYear())
304                 ts++;
305         }
306         if(b1.getYear().getValue()==b2.getYear().getValue()&&b1.getMonth().getValue()==b2.getMonth().getValue()){//年份相同,月份相同,日不同
307             ts=b2.getDay().getValue()-b1.getDay().getValue();
308         }
309         else if(b1.getYear().getValue()==b2.getYear().getValue()&&b1.getMonth().getValue()!=b2.getMonth().getValue()){//年份相同,月份不同
310             if(b1.getYear().isLeapYear())
311                 mon_maxnum[1]=29;
312             ts=ts+mon_maxnum[b1.getMonth().getValue()-1]-b1.getDay().getValue();
313             ts=ts+b2.getDay().getValue();
314             for(j=b1.getMonth().getValue()+1;j<=b2.getMonth().getValue()-1;j++)
315                 ts+=mon_maxnum[j-1];
316         }
317         else if(b1.getYear().getValue()!=b2.getYear().getValue()){
318             ts=ts+mon_maxnum[b1.getMonth().getValue()-1]-b1.getDay().getValue();
319             ts=ts+b2.getDay().getValue();
320             for(j=b1.getMonth().getValue()+1;j<=12;j++)
321                 ts=ts+mon_maxnum[j-1];
322             for(j=b2.getMonth().getValue()-1;j>0;j--)
323                 ts=ts+mon_maxnum[j-1];
324             if(b1.getYear().isLeapYear()&&b1.getMonth().getValue()<=2)
325                 ts++;
326             if(b2.getYear().isLeapYear()&&b2.getMonth().getValue()>2)
327                 ts++;
328         }
329         return ts;
330     }
331 }
332 
333 /*
334  **天类
335  */
336 
337 class Day
338 {
339     int value;
340     //Month month;
341     //int[] mon_maxnum ={31,28,31,30,31,30,31,31,30,31,30,31};
342     public Day()
343     {
344     }
345     public Day(int value)
346     {
347         this.value=value;
348     }
349     public int getValue() {
350         return value;
351     }
352 
353     public void setValue(int value) {
354         this.value = value;
355     }
356     public void dayIncrement()
357     {
358         value+=1;
359     }
360     public void dayReduction()
361     {
362         value-=1;
363     }
364 }
365 
366 /*
367  **月类
368  */
369 
370 class Month
371 {
372     int value;
373     public Month()
374     {
375     }
376     public Month(int value)
377     {
378         this.value=value;
379     }
380 
381     public int getValue() {
382         return value;
383     }
384 
385     public void setValue(int value) {
386         this.value = value;
387     }
388     public void resetMin()
389     {
390         value=1;
391     }
392     public void resetMax()
393     {
394         value=12;
395     }
396     public boolean validate()
397     {
398         return value >= 1 && value <= 12;
399     }
400     public void monthIncrement()
401     {
402         value+=1;
403     }
404     public void monthReduction()
405     {
406         value-=1;
407     }
408 }
409 
410 /*
411  **年类
412  * */
413 
414 class Year{
415     int value;
416     public Year(){
417     }
418     public Year(int value)
419     {
420         this.value=value;
421     }
422 
423     public int getValue() {
424         return value;
425     }
426 
427     public void setValue(int value) {
428         this.value = value;
429     }
430     public boolean isLeapYear()
431     {
432         return (value % 4 == 0 && value % 100 != 0) || (value % 400 == 0);
433     }
434     public boolean validate()
435     {
436         return value >= 1820 && value <= 2020;
437     }
438     public void yearIncrement()
439     {
440         value+=1;
441     }
442     public void yearReduction()
443     {
444         value-=1;
445     }
446 }
View Code

 

 

因两次代码差别没有很大,生成的报告都差不多,所以这里只给出(聚合二)的报告,(聚合一)也参照如上。

 

   两次题目内容都差不多,都是对于日期的各种求解,关键在于(聚合一)要求的类中Year类有对Day的set设置,Month类有对Year的set设置,Day类有对Month的set设置,这种类方法没有很好的表现出聚合该有的各种调用方法。

  (聚合二)中类之间的方法更加简洁,具有更好的封装性,没有对于本类之外的类的new,确保了数据的安全,防止随意的获取与修改。分析生成的检查报告,除最大圈复杂度外,其他都在合理的范围内,因为该题目思路比较清楚,各类都很好的执行了单一职责,Year、Month、Day各自执行自己的任务。圈复杂度超出合理范围也属于正常现象,因为DateUtil类中求前n天,后n天,两日期之间的天数要求使用非常多的循环,当n的天数非常大,超出年的跨月的时候,运行就尤其的花时间,需要一层一层的去先寻找年份,再去寻找月份,最后寻找天数,所以圈复杂度很大,可读性比较差。

 

 

(2)

题目集4(7-3)  图形继承 (15 分)

编写程序,实现图形类的继承,并定义相应类对象并进行测试。

  1. 类Shape,无属性,有一个返回0.0的求图形面积的公有方法public double getArea();//求图形面积
  2. 类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
  3. 类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
  4. 类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法public double getVolume();//求球体积
  5. 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法public double getVolume();//求立方体体积
  6. 注意:
  • 每个类均有构造方法,且构造方法内必须输出如下内容:Constructing 类名
  • 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
  • 输出的数值均保留两位小数
  1 import java.util.Scanner;
  2 public class Main {
  3     public static void main(String[] args){
  4         Scanner input=new Scanner(System.in);
  5         int choice=input.nextInt();
  6         if(choice==1)
  7         {
  8             
  9             double r=input.nextDouble();
 10             if(r<0)
 11             {
 12                 System.out.println("Wrong Format");
 13             }
 14             else
 15             {Circle c=new Circle();
 16                 c.setRadius(r);
 17                 System.out.printf("Circle's area:%.2f\n",c.getArea());
 18             }
 19         }
 20         else if(choice==2)
 21         {
 22             double lenth= input.nextDouble();
 23             double width= input.nextDouble();
 24 
 25             if(lenth<0||width<0)
 26             {
 27                 System.out.println("Wrong Format");
 28             }
 29             else
 30             {Rectangle R=new Rectangle();
 31                 R.setLength(lenth);
 32                 R.setWidth(width);
 33                 System.out.printf("Rectangle's area:%.2f\n",R.getArea());
 34             }
 35         }
 36         else if(choice==3)
 37         {
 38            
 39             double r= input.nextDouble();
 40 
 41             if(r<0)
 42             {
 43                 System.out.println("Wrong Format");
 44             }
 45             else
 46             { Ball B=new Ball();
 47                 B.setRadius(r);
 48                 System.out.println(String.format("Ball's surface area:%.2f",B.getArea()));
 49                 System.out.println(String.format("Ball's volume:%.2f",B.getVolume()));
 50             }
 51         }
 52         else if(choice==4)
 53         {
 54             
 55             double lenth= input.nextDouble();
 56             double width= input.nextDouble();
 57             double height= input.nextDouble();
 58             if(lenth<0||width<0||height<0)
 59             {
 60                 System.out.println("Wrong Format");
 61             }
 62             else
 63             {Box B=new Box();
 64                 B.setLength(lenth);
 65                 B.setWidth(width);
 66                 B.setHeight(height);
 67                 System.out.println(String.format("Box's surface area:%.2f",B.getArea()));
 68                 System.out.println(String.format("Box's volume:%.2f",B.getVolume()));
 69             }
 70         }
 71         else
 72         {
 73             System.out.println("Wrong Format");
 74         }
 75     }
 76 }
 77 class Shape{
 78     public Shape() {
 79         System.out.println("Constructing Shape");
 80     }
 81     public double getArea() {
 82         return 0.0;
 83     }
 84 }
 85 class Circle extends Shape
 86 {
 87     private double radius;
 88     public Circle()
 89     {
 90         System.out.println("Constructing Circle");
 91     }
 92 
 93     public double getArea()
 94     {
 95         return Math.PI*radius*radius;
 96     }
 97 
 98     public double getRadius() {
 99         return radius;
100     }
101     public void setRadius(double radius) {
102         this.radius = radius;
103     }
104 }
105 class Rectangle extends Shape
106 {
107     public Rectangle()
108     {
109         System.out.println("Constructing Rectangle");
110     }
111     private double width;
112     private double length;
113     public double getWidth() {
114         return width;
115     }
116     public void setWidth(double width) {
117         this.width = width;
118     }
119     public double getLength() {
120         return length;
121     }
122     public void setLength(double length) {
123         this.length = length;
124     }
125     public double getArea() {
126         return width*length;
127     }
128 }
129 class Ball extends Circle
130 {
131     public Ball()
132     {
133         System.out.println("Constructing Ball");
134     }
135     public double getArea() {
136         return 4*super.getArea();
137     }
138     public double getVolume()
139     {
140         double r2=getRadius();
141         return 4.0/3*r2*r2*r2*Math.PI;
142     }
143 }
144 class Box extends Rectangle {
145     public Box() {
146         System.out.println("Constructing Box");
147     }
148     private double height;
149     public double getVolume() {
150         return super.getArea() * height;//父类的面积
151     }
152     public double getHeight() {
153         return height;
154     }
155     public void setHeight(double height) {
156         this.height = height;
157     }
158     public double getArea() {
159         double l = getWidth();
160         double j = getLength();
161         return (l * j * 2 + j * height * 2 + l * height * 2);
162     }
163 }
View Code

 

 

 

  该题实现了图形的继承,从Power Designer生成的类图来看,Rectangle类继承Shape,类Circle继承自Shape,类Ball继承自Circle,类Box继承自Rectangle。Shape类中定义了无属性的两个方法,都没有实际意义,仅供子类继承,实际的获取面积、体积方法都是在各个子类当中定义方法来实现的,父类当中定义各类图形的共同属性。

  根据SourceMonitor生成的检查报告,除最大圈复杂度外,其他方面都显示代码良好。

 

题目集6(7-5)  图形继承与多态 (50 分)
 掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。

 

  1 import java.util.Scanner;
  2 import java.util.ArrayList;
  3 public class Main {
  4     public static void main(String[] args)
  5     {
  6         Scanner input=new Scanner(System.in);
  7         int a=input.nextInt();
  8         int b=input.nextInt();
  9         int c=input.nextInt();
 10         double sum=0.0;
 11         ArrayList<Shape> arr=new ArrayList<>();
 12         if(a>=0&&b>=0&&c>=0)
 13         {
 14             for(int i=0;i<a;i++)
 15             {
 16                 double radius= input.nextDouble();
 17                 arr.add(i,new Circle(radius));
 18             }
 19             for(int i=a;i<a+b;i++)
 20             {
 21                 double width= input.nextDouble();
 22                 double length= input.nextDouble();
 23                 arr.add(i,new Rectangle(width,length));
 24             }
 25             for(int i=a+b;i<a+b+c;i++) {
 26                 double side1 = input.nextDouble();
 27                 double side2 = input.nextDouble();
 28                 double side3 = input.nextDouble();
 29                 arr.add(i, new Triangle(side1, side2, side3));
 30             }
 31             for(int i=0;i<a+b+c;i++)
 32             {
 33                 if(!arr.get(i).validate())
 34                 {
 35                     System.out.println("Wrong Format");
 36                     System.exit(0);
 37                 }
 38             }
 39             System.out.println("Original area:");
 40             for(int i=0;i<a;i++)
 41             {
 42                 System.out.print(String.format("%.2f",arr.get(i).getArea()) + " ");
 43             }
 44             for(int i=a;i<a+b;i++)
 45             {
 46                 System.out.print(String.format("%.2f", arr.get(i).getArea()) + " ");
 47             }
 48             for (int i = a + b; i < a + b + c; i++) {
 49                 System.out.print(String.format("%.2f", arr.get(i).getArea()) + " ");
 50             }
 51             System.out.println();
 52             for(int i=0;i<a+b+c;i++)
 53             {
 54                 sum+=arr.get(i).getArea();
 55             }
 56             System.out.println("Sum of area:" + String.format("%.2f", sum));
 57             System.out.println("Sorted area:");
 58             sort(arr);
 59             for (int i = 0; i < a + b + c; i++) {
 60                 System.out.print(String.format("%.2f", arr.get(i).getArea()) + " ");
 61             }
 62             System.out.println();
 63             System.out.println("Sum of area:" + String.format("%.2f", sum));
 64         }
 65         else
 66         {
 67             System.out.println("Wrong Format");
 68         }
 69     }
 70     public static ArrayList<Shape> sort(ArrayList<Shape> arr)
 71     {
 72         int i,j;
 73         Shape temp;
 74         for(i=0;i<arr.size()-1;i++)
 75         {
 76             int mindex=i;
 77             for(j=i+1;j< arr.size();j++)
 78             {
 79                 if(arr.get(j).getArea()<arr.get(mindex).getArea())
 80                 {
 81                     mindex=j;
 82                 }
 83             }
 84             temp=arr.get(i);
 85             arr.set(i,arr.get(mindex));
 86             arr.set(mindex,temp);
 87         }
 88         return arr;
 89     }
 90 }
 91 abstract class Shape
 92 {
 93     abstract public double getArea();
 94     abstract public boolean validate();
 95 }
 96 class Circle extends Shape
 97 {
 98     private double radius;
 99     public Circle(){}
100     public Circle(double radius){
101         this.radius=radius;
102     }
103 
104     public void setRadius(double radius) {
105         this.radius = radius;
106     }
107 
108     public double getRadius() {
109         return radius;
110     }
111 
112     public double getArea() {
113         return Math.PI* Math.pow(radius,2);
114     }
115     public boolean validate()
116     {
117         if(radius<=0)
118         {
119             return false;
120         }
121         else
122         {
123             return true;
124         }
125     }
126 
127 }
128 class Rectangle extends Shape
129 {
130     private double width;
131     private double length;
132     public Rectangle(){}
133     public Rectangle(double width,double length){
134         this.length=length;
135         this.width=width;
136     }
137     public void setLength(double length) {
138         this.length = length;
139     }
140 
141     public double getLength() {
142         return length;
143     }
144 
145     public double getWidth() {
146         return width;
147     }
148 
149     public void setWidth(double width) {
150         this.width = width;
151     }
152 
153     public double getArea() {
154         return width*length;
155     }
156     public boolean validate()
157     {
158         if(width<0||length<0)
159         {
160             return false;
161         }
162         else
163         {
164             return true;
165         }
166     }
167 }
168 class Triangle extends Shape
169 {
170     private double side1;
171     private double side2;
172     private double side3;
173     public Triangle(){}
174     public Triangle(double side1,double side2,double side3)
175     {
176         this.side1=side1;
177         this.side2=side2;
178         this.side3=side3;
179     }
180 
181     public double getSide2() {
182         return side2;
183     }
184 
185     public void setSide2(double side1) {
186         this.side2 = side2;
187     }
188 
189     public double getSide3() {
190         return side3;
191     }
192 
193     public void setSide3(double side3) {
194         this.side3 = side3;
195     }
196     public double getArea()
197     {
198         double p=(side1+side2+side3)/2;
199         return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3));
200     }
201     public boolean validate()
202     {
203         if(side1+side2<=side3||side1+side3<=side2||side2+side3<=side1)
204         {
205             return false;
206         }
207         if(side1-side2>=side3||side1-side3>=side2||side2-side3>=side1)
208         {
209             return false;
210         }
211         else
212         {
213             return true;
214         }
215     }
216 }
View Code

 

 

 

   这题要求求不同数量的各种图形单个面积以及总面积,在输入图形数量时使用ArrayList<Shape> arr定义一个可以存储图形的数组,这个数组可以像存储数字一样将Shape类的图形包括其属性、方法存储起来,然后利用循环计算图形面积存入arr中。

  输出面积时通过数组类似于arr.get(i).getArea()获取面积输出。类图中Circle、Rectangle、Triangle类都继承类Shape,类Shape中仅定义获取面积、判断合法性方法,实际的计算判断等方法则要通过多态改写父类。

 

 题目集6(7-6)实现图形接口及多态性 (30 分) 

编写程序,使用接口及类实现多态性,类图结构如下所示:

 

其中:

  • GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
  • Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
  • 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)
 1 import java.util.Scanner;
 2 public class Main {
 3     public static void main(String[] args)
 4     {
 5         Scanner input=new Scanner(System.in);
 6         double radius= input.nextDouble();
 7         double width= input.nextDouble();
 8         double length= input.nextDouble();
 9         if(radius<=0||width<=0||length<=0)
10         {
11             System.out.println("Wrong Format");
12         }
13         else {
14             Circle c = new Circle(radius);
15             Rectangle R = new Rectangle(width,length);
16             System.out.printf("%.2f\n",c.getArea());
17             System.out.printf("%.2f\n",R.getArea());
18         }
19     }
20 }
21 class GetArea
22 {
23     public double getArea()
24     {
25         return 0.0;
26     }
27 }
28 class Circle extends GetArea
29 {
30     private double radius;
31 
32     public double getRadius() {
33         return radius;
34     }
35 
36     public void setRadius(double radius) {
37         this.radius = radius;
38     }
39     public Circle(double radius)
40     {
41         this.radius=radius;
42     }
43     public Circle()
44     {
45 
46     }
47     public double getArea()
48     {
49         return Math.PI*Math.pow(radius,2);
50     }
51 }
52 class Rectangle extends GetArea
53 {
54     private double width;
55     private double length;
56 
57     public double getWidth() {
58         return width;
59     }
60 
61     public void setWidth(double width) {
62         this.width = width;
63     }
64 
65     public double getLength() {
66         return length;
67     }
68 
69     public void setLength(double length) {
70         this.length = length;
71     }
72     public Rectangle(double width,double length)
73     {
74         this.length=length;
75         this.width=width;
76     }
77     public Rectangle()
78     {
79     }
80     public double getArea()
81     {
82         return width*length*1.0;
83     }
84 }
View Code

 

 

 

 

   从SourceMonitor生成的检查报告就可以看出,代码的各方面都良好,包括圈复杂度,题目并不难,要求也比前两个少,只需要求Circle、Rectangle两种图形的面积。

GetArea作为一个接口定义求面积的抽象方法,Circle、Rectangle通过接口实现了多态求面积。

 

  前两次作业是从继承到多态的一种简单过渡,通过第一次的简单继承使得拥有的共同属性能够提炼出一个公共类来涵盖他们,这个公共类就是父类,父类中拥有子类共有的属性和方法,子类可以通过继承父类来继承这些属性和方法。到第二次同样继承父类的情况下,在子类当中再次重写父类方法,这种重写就是多态。两次题目其实差不了多少,第二次是在第一次的基础上实现了更加复杂的计算方法,运用了多态。而第三次相比于前两次就更加简单了,没有过多要求,仅用接口实现面积求解。

 

(3)对三次题目集中用到的正则表达式技术的分析总结

   我在这三次题目集中主要在题目集4、5中使用了正则表达式。正则表达式在字符判定方面确实非常的方便且实用,只用通过一串语句便可以将字符串每一位都判断到,可以完美降低全复杂度,使代码更加的简洁。

  需要注意的是,使用正则表达式匹配特殊字符本身的时候,一定要记得加上反斜杠 “ \ ”,另外需要灵活使用“通配符”,但排除范围内字符的话需要使用[ ]进行匹配,同样的方便,且更加灵活。

  总的来说,在处理字符串的时候尽量多使用正则表达式,也要灵活的处理,可以提高程序的运行效率。

 

(4)题目集5(7-4)中Java集合框架应用的分析总结

 对于关键字的提取与出现次数的计算,使用正则表达式可以很灵活方便的处理。

 输入的代码根据空格、括号以及特殊字符等进行划分,使用Map进行操作。

 由于关键字、非关键字、注释等处理方式都不同,主要可以就这三类进行正则匹配。

 另外处理注释的时候,\\起到了主要作用,因此需要先对注释进行处理后再进行其他字符的处理。

    在最后输出时使用了Set接口输出。

 

三、踩坑心得

  题目集4日期问题面向对象设计(聚合一)和题目集5日期问题面向对象设计(聚合二)两题类似,包含的内容非常多,计算量也很大,类当中的方法、属性定义也有很多,总之非常复杂。

  实现求日期前、后n天我用了最常规但也是最复杂的循环,层层嵌套,一年一年、一月一月去找,直到找到为止。这种方法很容易出错,一不小心就漏了哪一年什么的。

  我在(聚合一)中求前n天时出现了错误,日期怎么也不符,最后发现是在判断日期合法性时没有判断闰年。(聚合二)也是提交的时候出现了日期对不上的错误,最后检查还是闰年的判断出现了问题。

  所以这两题对闰年的判断很重要,一不小心漏了的话就出错了。

 

  题目集5中的统计Java关键字我没有全对,据说是因为当null存在时,计算发生了错误,我试着改了一下,加入了对null的判断,结果答案还是错误的。

报错截图如下:

 

四、改进建议

  求日期的聚合题可以换一种求n天的方法,减少计算次数。我觉得可以直接用天去算,通过天数一次循环找出年、月、日,而不要在年、月、日上依次去循环,增加圈复杂度。

  还可以在这段闰年判断上进一步考虑,细化各种情况,在判断合法值和循环计算n天的时候加上,以免出现各种小错误。

 

 

   其他正则上的匹配也要注意反斜杠 “ \ ”,另外需要灵活使用“通配符”,排除范围内字符的话需要使用[ ]进行匹配。

  图形的继承、多态完成题目要求比较简单,值得注意的是要记得对数据进行封装,保证安全性。

 

五、总结

  通过这几次的题目,我能够更好的运用正则表达式,体会到了正则的灵活与强大之处。

  同时对于类的继承、多态等,设计一个合理的类能够应对各种要求的改变,高效的对代码进行处理,还可以降低代码中的圈复杂度,减少判断语句的使用。在今后的设计中应多加使用。

  本次作业当中我也发现了自己对于正则还是不太熟练,写正则匹配的时候经常写错,忘记加"[]"和"/",浪费了太多时间花在改正正则上。课后应该多花些时间去了解正则的基本使用方法,并将它们熟记下来,多做一做基础的题目,提高正确率,避免不必要的错误。

 

posted @ 2021-11-13 16:21  chi_qian  阅读(52)  评论(0)    收藏  举报