第二次作业总结
一、前言
这三次作业主要包括正则表达式的运用以及图形类的继承、多态知识点。
第四次作业当中的水文校验及处理需要运用到非常多的正则表达式以及对String类的各种方法的运用,计算量非常大,任务繁杂,要注意的细节也很多。日期问题面向对象设计对于类的聚合关系也有了严格要求,同样计算量非常大,但有了各种类图框架,其中的类与类之间的聚合关系就简单了一点。
第五次作业中的统计Java程序中关键字的出现次数也主要是以正则表达式为主,但较之于水文处理,题量明显减小了不少。且题目中要求用到接口类辅助做题,有了Map接口和正则表达式的使用,使得题目对于字符统计更加简单。这次作业的聚合题和第四次作业差不多,减少了年、月、日类当中各类的含参方法,而是直接使用类之间的聚合关系。
第六次作业题量虽然多了一点,但大多数都是比较基础的正则匹配,难度很小。图形继承题也比较基础。
二、设计与分析
(1)
题目集4(7-2)日期问题面向对象设计(聚合一)
参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
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 }
题目集5(7-4)日期问题面向对象设计(聚合二)
参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
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 }

因两次代码差别没有很大,生成的报告都差不多,所以这里只给出(聚合二)的报告,(聚合一)也参照如上。
两次题目内容都差不多,都是对于日期的各种求解,关键在于(聚合一)要求的类中Year类有对Day的set设置,Month类有对Year的set设置,Day类有对Month的set设置,这种类方法没有很好的表现出聚合该有的各种调用方法。
(聚合二)中类之间的方法更加简洁,具有更好的封装性,没有对于本类之外的类的new,确保了数据的安全,防止随意的获取与修改。分析生成的检查报告,除最大圈复杂度外,其他都在合理的范围内,因为该题目思路比较清楚,各类都很好的执行了单一职责,Year、Month、Day各自执行自己的任务。圈复杂度超出合理范围也属于正常现象,因为DateUtil类中求前n天,后n天,两日期之间的天数要求使用非常多的循环,当n的天数非常大,超出年的跨月的时候,运行就尤其的花时间,需要一层一层的去先寻找年份,再去寻找月份,最后寻找天数,所以圈复杂度很大,可读性比较差。
(2)
题目集4(7-3) 图形继承 (15 分)
编写程序,实现图形类的继承,并定义相应类对象并进行测试。
- 类Shape,无属性,有一个返回0.0的求图形面积的公有方法
public double getArea();//求图形面积 - 类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
- 类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
- 类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法
public double getVolume();//求球体积 - 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法
public double getVolume();//求立方体体积 - 注意:
- 每个类均有构造方法,且构造方法内必须输出如下内容:
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 }


该题实现了图形的继承,从Power Designer生成的类图来看,Rectangle类继承Shape,类Circle继承自Shape,类Ball继承自Circle,类Box继承自Rectangle。Shape类中定义了无属性的两个方法,都没有实际意义,仅供子类继承,实际的获取面积、体积方法都是在各个子类当中定义方法来实现的,父类当中定义各类图形的共同属性。
根据SourceMonitor生成的检查报告,除最大圈复杂度外,其他方面都显示代码良好。
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 }


这题要求求不同数量的各种图形单个面积以及总面积,在输入图形数量时使用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 }

从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天的时候加上,以免出现各种小错误。
其他正则上的匹配也要注意反斜杠 “ \ ”,另外需要灵活使用“通配符”,排除范围内字符的话需要使用[ ]进行匹配。
图形的继承、多态完成题目要求比较简单,值得注意的是要记得对数据进行封装,保证安全性。
五、总结
通过这几次的题目,我能够更好的运用正则表达式,体会到了正则的灵活与强大之处。
同时对于类的继承、多态等,设计一个合理的类能够应对各种要求的改变,高效的对代码进行处理,还可以降低代码中的圈复杂度,减少判断语句的使用。在今后的设计中应多加使用。
本次作业当中我也发现了自己对于正则还是不太熟练,写正则匹配的时候经常写错,忘记加"[]"和"/",浪费了太多时间花在改正正则上。课后应该多花些时间去了解正则的基本使用方法,并将它们熟记下来,多做一做基础的题目,提高正确率,避免不必要的错误。

浙公网安备 33010602011771号