OO第二次博客作业
前言:
这三次的题目的难度还是有点跳跃,主要在跟随课程进度的题目上还是循序渐进的,到了要求学习的正则上难度跨越波动就比较大。第四次的题集第一题很繁琐,有点涉及到不知道的领域了,后面两题则是关于聚合继承的运用,难度适中吧,总体题量不是很大;第五次题集内容除了一个7-4都还好,基本上是java的排序和上次的聚合重写,7-4这个正则的考察对我来说确实很有难度,感觉和前面写的差距都有些大,题量大概中等;第六次题集基本上是一些简单的正则加上继承多态和接口的考察,做的时候感觉这个正则的难度应该放前面会好点,正则的难度这几次来看就时难时易的,落差很大,另外两题就还好,题量的话中等。
设计与分析:
①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较
7-2 日期问题面向对象设计(聚合一) (35 分)
参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
- 1 year month day n //测试输入日期的下n天
- 2 year month day n //测试输入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
- 当输入有误时,输出格式如下:
Wrong Format
- 当第一个数字为1且输入均有效,输出格式如下:
year-month-day
- 当第一个数字为2且输入均有效,输出格式如下:
year-month-day
- 当第一个数字为3且输入均有效,输出格式如下:
天数值
7-5 日期问题面向对象设计(聚合二) (40 分)
参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
- 1 year month day n //测试输入日期的下n天
- 2 year month day n //测试输入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
- 当输入有误时,输出格式如下:
Wrong Format
- 当第一个数字为1且输入均有效,输出格式如下:
year1-month1-day1 next n days is:year2-month2-day2
- 当第一个数字为2且输入均有效,输出格式如下:
year1-month1-day1 previous n days is:year2-month2-day2
- 当第一个数字为3且输入均有效,输出格式如下:
The days between year1-month1-day1 and year2-month2-day2 are:
1 import java.util.*; 2 public class Main { 3 public static void main(String[] args){ 4 Scanner in=new Scanner(System.in); 5 int x; 6 String y[]; 7 String s=in.nextLine(); 8 DataUtil dataUtil; 9 DataUtil dataUtil_2=new DataUtil(); 10 if(s.matches("(\\d\\s\\d+\\s\\d+\\s\\d+\\s\\d+)+|(\\d\\s\\d+\\s\\d+\\s\\d+\\s\\d+\\s\\d+\\s\\d+)")) 11 { 12 y=s.split(" "); 13 x=Integer.parseInt(y[0]); 14 dataUtil=new DataUtil(Integer.parseInt(y[1]),Integer.parseInt(y[2]),Integer.parseInt(y[3])); 15 if(x>=1&&x<=3&&dataUtil.getDay().validata()&&dataUtil.getDay().getMonth().getYear().validate()) 16 { 17 switch (x) 18 { 19 case 1: 20 dataUtil_2=dataUtil.getNextNdays(Long.parseLong(y[4])); 21 System.out.println(dataUtil.showData()+" next "+Integer.parseInt(y[4])+" days is:"+dataUtil_2.showData()); 22 break; 23 case 2: 24 dataUtil_2=dataUtil.getPreviousNdays(Integer.parseInt(y[4])); 25 System.out.println(dataUtil.showData()+" previous "+Integer.parseInt(y[4])+" days is:"+dataUtil_2.showData()); 26 break; 27 case 3: 28 dataUtil_2=new DataUtil(Integer.parseInt(y[4]),Integer.parseInt(y[5]),Integer.parseInt(y[6])); 29 System.out.println("The days between "+dataUtil.showData()+" and "+dataUtil_2.showData()+" are:"+dataUtil.getDayssofDates(dataUtil_2)); 30 } 31 } 32 else 33 System.out.println("Wrong Format"); 34 35 } 36 else 37 System.out.println("Wrong Format"); 38 39 } 40 } 41 42 class Year{ 43 private int value; 44 45 Year(){} 46 Year(int value){ 47 this.value=value; 48 } 49 50 public int getValue() { 51 return value; 52 } 53 54 public void setValue(int value) { 55 this.value = value; 56 } 57 public boolean isLeapYear(){ 58 if((value%4==0&&value%100!=0)||(value%400==0)) 59 return true; 60 else 61 return false; 62 } 63 public boolean validate(){ 64 if(value>=1820&&value<=2020) 65 return true; 66 else 67 return false; 68 } 69 public void yearIncremment(){ 70 value++; 71 } 72 public void yearReduction(){ 73 value--; 74 } 75 } 76 77 class Month{ 78 private int value; 79 private Year year; 80 81 Month(){} 82 Month(int yearValue,int monthValue){ 83 this.value=monthValue; 84 year=new Year(yearValue); 85 } 86 87 public int getValue() { 88 return value; 89 } 90 91 public void setValue(int value) { 92 this.value = value; 93 } 94 95 public Year getYear() { 96 return year; 97 } 98 99 public void setYear(Year year) { 100 this.year = year; 101 } 102 public void resetMin(){ 103 this.value=1; 104 } 105 public void resetMax(){ 106 this.value=12; 107 } 108 public boolean validata(){ 109 boolean f=false; 110 if(value>=1&&value<=12) 111 f=true; 112 return f; 113 } 114 public void monthIncrement(){ 115 this.value++; 116 } 117 public void monthReduction(){ 118 this.value--; 119 } 120 } 121 class Day{ 122 private int value; 123 private Month month; 124 private int mon_maxnum[]={31,28,31,30,31,30,31,31,30,31,30,31}; 125 126 Day(){} 127 Day(int yearValue,int monthValue,int dayValue){ 128 this.value=dayValue; 129 month=new Month(yearValue,monthValue); 130 } 131 132 public int getValue() { 133 return value; 134 } 135 136 public void setValue(int value) { 137 this.value = value; 138 } 139 140 public Month getMonth() { 141 return month; 142 } 143 144 public void setMonth(Month month) { 145 this.month = month; 146 } 147 public void resetMin(){ 148 this.value=1; 149 } 150 public void resetMax(){ 151 this.value=mon_maxnum[month.getValue()-1]; 152 } 153 public boolean validata(){ 154 boolean f=false; 155 if(month.validata()) 156 { 157 if(month.getYear().isLeapYear()) 158 mon_maxnum[1]=29; 159 else 160 mon_maxnum[1]=28; 161 if(this.value>=1&&this.value<=mon_maxnum[month.getValue()-1]) 162 f=true; 163 } 164 165 return f; 166 } 167 public void dayIncrement(){ 168 this.value++; 169 } 170 public void dayReduction(){ 171 this.value--; 172 } 173 } 174 175 class DataUtil{ 176 private Day day; 177 178 DataUtil(){} 179 DataUtil(int y,int m,int d){ 180 day=new Day(y,m ,d); 181 } 182 183 public Day getDay() { 184 return day; 185 } 186 187 public void setDay(Day day) { 188 this.day = day; 189 } 190 191 public boolean checkInValidity(){ 192 if(day.validata()) 193 return true; 194 else 195 return false; 196 } 197 public static boolean isLeapYear(int year) {//判断year是否为闰年,返回boolean类型; 198 boolean isLeapYear=(year%4==0&&year%100!=0)||year%400==0; 199 return isLeapYear; 200 } 201 public static boolean checkInputValidity(int year,int month,int day){//判断输入日期是否合法,返回布尔值 202 int[] leapmon=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31}; 203 int[] mon=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; 204 if(year>=1900&&year<=2000){ 205 if(month>=1&&month<=12){ 206 if(isLeapYear(year)){ 207 if(day<=leapmon[month]&&day>=1){ 208 return true; 209 } 210 else 211 return false; 212 } 213 else if(day<=mon[month]&&day>=1){ 214 return true; 215 } 216 else 217 return false; 218 } 219 else 220 return false; 221 } 222 else 223 return false; 224 } 225 public static void nextDate(int year,int month,int day){//求输入日期的下一天 226 int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; 227 if(isLeapYear(year)) 228 a[2]=29; 229 if(checkInputValidity(year,month,day)){ 230 if(month==12){ 231 if(day==a[month]){ 232 year+=1; 233 month=1; 234 day=1; 235 } 236 else 237 day+=1; 238 } 239 else{ 240 if(day==a[month]){ 241 month+=1; 242 day=1; 243 } 244 else 245 day+=1; 246 } 247 System.out.println("Next day is:"+year+"-"+month+"-"+day); 248 } 249 else 250 System.out.println("Date Format is Wrong"); 251 } 252 public boolean compareDates(DataUtil date){//day是否大于data 是true 否false 253 boolean f=false; 254 if(this.day.getMonth().getYear().getValue()>date.day.getMonth().getYear().getValue()) 255 f=true; 256 else if(this.day.getMonth().getYear().getValue()<date.day.getMonth().getYear().getValue()) 257 f=false; 258 else 259 { 260 if(this.day.getMonth().getValue()>date.day.getMonth().getValue()) 261 f=true; 262 else if(this.day.getMonth().getValue()<date.day.getMonth().getValue()) 263 f=false; 264 else 265 { 266 if(this.day.getValue()>date.day.getValue()) 267 f=true; 268 else 269 f=false; 270 } 271 } 272 return f; 273 } 274 public boolean equalTwoDates(DataUtil date){ 275 boolean f=false; 276 if(this.day.getMonth().getYear().getValue()==date.day.getMonth().getYear().getValue()) 277 if(this.day.getMonth().getValue()==date.day.getMonth().getValue()) 278 if(this.day.getValue()==date.day.getValue()) 279 f=true; 280 return f; 281 } 282 283 public String showData(){ 284 return day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue(); 285 } 286 287 public DataUtil getNextNdays(long n){ 288 DataUtil data; 289 data=new DataUtil(this.day.getMonth().getYear().getValue(),this.day.getMonth().getValue(),this.day.getValue()); 290 int i=0; 291 for(i=0;i) { 292 data.day.dayIncrement(); 293 if (!data.day.validata()) 294 { 295 data.day.getMonth().monthIncrement(); 296 if(data.day.getMonth().validata()) 297 data.day.resetMin(); 298 else if (!data.day.getMonth().validata()) 299 { 300 data.day.getMonth().getYear().yearIncremment(); 301 data.day.getMonth().resetMin(); 302 data.day.resetMin(); 303 } 304 } 305 306 } 307 return data; 308 } 309 public DataUtil getPreviousNdays(long n){ 310 DataUtil data; 311 data=new DataUtil(this.day.getMonth().getYear().getValue(),this.day.getMonth().getValue(),this.day.getValue()); 312 int i=0; 313 for(i=0;i ) { 314 data.day.dayReduction(); 315 if (!data.day.validata()) 316 { 317 data.day.getMonth().monthReduction(); 318 if (data.day.getMonth().validata()) 319 data.day.resetMax(); 320 else if (!data.day.getMonth().validata()) 321 { 322 data.day.getMonth().getYear().yearReduction(); 323 data.day.getMonth().resetMax(); 324 data.day.resetMax(); 325 } 326 } 327 } 328 return data; 329 } 330 public int getDayssofDates(DataUtil data){ 331 int n=0; 332 DataUtil data_2=new DataUtil(); 333 data_2.setDay(this.getDay()); 334 if(data_2.equalTwoDates(data)) 335 n=0; 336 else if(data_2.compareDates(data)) 337 { 338 DataUtil data_3=new DataUtil(); 339 data_3.setDay(data_2.getDay()); 340 data_2.setDay(data.getDay()); 341 data.setDay(data_3.getDay()); 342 } 343 for(n=0;!data_2.equalTwoDates(data);n++) 344 data_2.setDay(data_2.getNextNdays(1).getDay()); 345 return n; 346 } 347 }
总的来说这两道题目从输入输出上看差别不大,第二题就是输出格式变了一些,但是从类图上来看,使用了两种聚合方式,第一题中要求DateUtil聚合Day,Day聚合Month,Month聚合Year,这样嵌套聚合虽然结构更清晰,但是嵌合调用十分繁琐,需要一层层进行,代码的效率低下,第二题中则要求DateUtil聚合Year,Month,Day,这样类中方法繁多,但是调用起来是直接调用,代码的效率更高。
分析SourceMonitor给出的图可得其平均复杂度更低,效率更高,但同时块平均深度和最大深度也很高,还需要继续优化。
②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
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-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;
假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format
输入格式:
共四种合法输入
- 1 圆半径
- 2 矩形宽、长
- 3 球半径
- 4 立方体宽、长、高
输出格式:
按照以上需求提示依次输出
1 import java.util.*; 2 class Shape{ 3 public Shape(){ 4 System.out.println("Constructing Shape"); 5 } 6 public double getArea(){ 7 return 0.0; 8 } 9 } 10 class Circle extends Shape{ 11 private double radius; 12 public Circle(){ 13 System.out.println("Constructing Circle"); 14 } 15 public double getArea(){ 16 return Math.PI*radius*radius; 17 } 18 public double getradius(){ 19 return radius; 20 } 21 public void setradius(double radius){ 22 this.radius=radius; 23 } 24 } 25 class Rectangle extends Shape{ 26 private double width; 27 private double length; 28 public Rectangle(){ 29 System.out.println("Constructing Rectangle"); 30 } 31 public double getArea(){ 32 return width*length; 33 } 34 public double getwidth(){ 35 return width; 36 } 37 public void setwidth(double width){ 38 this.width=width; 39 } 40 public double getlength(){ 41 return length; 42 } 43 public void setlength(double length){ 44 this.length=length; 45 } 46 } 47 class Ball extends Circle{ 48 public Ball(){ 49 System.out.println("Constructing Ball"); 50 } 51 public double getbArea(){ 52 return 4*super.getArea(); 53 } 54 public double getVolume(){ 55 double radiu=getradius(); 56 return Math.PI*radiu*radiu*radiu*4/3.0; 57 } 58 } 59 class Box extends Rectangle{ 60 private double height; 61 public Box(){ 62 System.out.println("Constructing Box"); 63 } 64 public double getbArea(){ 65 double widt=getwidth(); 66 double lengt=getlength(); 67 return (widt*height+lengt*height+widt*lengt)*2; 68 } 69 public double getVolume(){ 70 return super.getArea()*height; 71 } 72 public double getheight(){ 73 return height; 74 } 75 public void setheight(double height){ 76 this.height=height; 77 } 78 } 79 public class Main{ 80 public static void main(String[] args){ 81 Scanner cin=new Scanner(System.in); 82 int n=cin.nextInt(); 83 switch(n){ 84 case 1: 85 double radius; 86 radius=cin.nextDouble(); 87 if(radius<=0) 88 System.out.println("Wrong Format"); 89 else{ 90 Circle a=new Circle(); 91 a.setradius(radius); 92 System.out.printf("Circle's area:%.2f\n",a.getArea()); 93 } 94 break; 95 case 2: 96 double width,length; 97 width=cin.nextDouble(); 98 length=cin.nextDouble(); 99 if(width<=0||length<=0) 100 System.out.println("Wrong Format"); 101 else{ 102 Rectangle c=new Rectangle(); 103 c.setwidth(width); 104 c.setlength(length); 105 System.out.printf("Rectangle's area:%.2f\n",c.getArea()); 106 } 107 if(n==0) 108 n=1; 109 else 110 n=0; 111 break; 112 case 3: 113 double radiu; 114 radiu=cin.nextDouble(); 115 if(radiu<=0) 116 System.out.println("Wrong Format"); 117 else{ 118 Ball a=new Ball(); 119 a.setradius(radiu); 120 System.out.printf("Ball's surface area:%.2f\n",a.getbArea()); 121 System.out.printf("Ball's volume:%.2f\n",a.getVolume()); 122 } 123 break; 124 case 4: 125 double widt; 126 double lengt; 127 double height; 128 widt=cin.nextDouble(); 129 lengt=cin.nextDouble(); 130 height=cin.nextDouble(); 131 if(widt<=0||lengt<=0||height<=0) 132 System.out.println("Wrong Format"); 133 else{ 134 Box a=new Box(); 135 a.setwidth(widt); 136 a.setlength(lengt); 137 a.setheight(height); 138 System.out.printf("Box's surface area:%.2f\n",a.getbArea()); 139 System.out.printf("Box's volume:%.2f\n",a.getVolume()); 140 } 141 if(n==0) 142 n=1; 143 else 144 n=0; 145 break; 146 default: 147 System.out.println("Wrong Format"); 148 break; 149 } 150 } 151 }
7-5 图形继承与多态 (50 分)
掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。
2021-OO第06次作业-5指导书V1.0.pdf
输入格式:
从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出
Wrong Format
。 - 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
- 各个图形的面积;
- 所有图形的面积总和;
- 排序后的各个图形面积;
- 再次所有图形的面积总和。
1 import java.util.*; 2 class Shape{ 3 public double getArea(){ 4 return 0.0; 5 } 6 } 7 class Circle extends Shape{ 8 private double radius; 9 public double getArea(){ 10 return Math.PI*radius*radius; 11 } 12 public double getradius(){ 13 return radius; 14 } 15 public Circle(double radius) { 16 super(); 17 this.radius = radius; 18 } 19 public boolean isCircle(){ 20 return radius>0; 21 } 22 } 23 class Rectangle extends Shape{ 24 private double width; 25 private double length; 26 public double getArea(){ 27 return width*length; 28 } 29 public double getwidth(){ 30 return width; 31 } 32 public Rectangle(double width, double length){ 33 super(); 34 this.width = width; 35 this.length = length; 36 } 37 public void setlength(double length){ 38 this.length=length; 39 } 40 public boolean isRectangle() { 41 return width > 0 && length > 0; 42 } 43 } 44 class Triangle extends Shape{ 45 private double a; 46 private double b; 47 private double c; 48 public Triangle(double a, double b, double c) { 49 this.a = a; 50 this.b = b; 51 this.c = c; 52 } 53 public double getArea() { 54 double p=(a+b+c)/2; 55 return Math.sqrt(p*(p-a)*(p-b)*(p-c)); 56 } 57 public boolean isTriangle() { 58 if (a < 0 || b < 0 || c < 0) { 59 return false; 60 } 61 double[] sides = new double[3]; 62 sides[0] = a; 63 sides[1] = b; 64 sides[2] = c; 65 Arrays.sort(sides); 66 return sides[0] + sides[1] > sides[2]; 67 } 68 } 69 public class Main{ 70 public static void main(String[] args){ 71 Scanner x = new Scanner(System.in); 72 int q,w,e,gs=0,h; 73 q=x.nextInt();w=x.nextInt();e=x.nextInt(); 74 if(q<0||w<0||e<0){ 75 System.out.println("Wrong Format"); 76 System.exit(0); 77 } 78 h=q+w+e; 79 double[] he=new double [q+w+e]; 80 double zh=0; 81 int i,flag=0; 82 Shape []c=new Circle[q]; 83 Shape []r=new Rectangle[w]; 84 Shape []t=new Triangle[e]; 85 for(i=0;i){ 86 double bj; 87 bj=x.nextDouble(); 88 if(bj<=0){ 89 flag=1; 90 } 91 c[i]=new Circle(bj); 92 zh=zh+c[i].getArea(); 93 he[gs]=c[i].getArea(); 94 gs++; 95 } 96 for(i=0;i){ 97 double db; 98 double cb; 99 db=x.nextDouble();cb=x.nextDouble(); 100 if(db<0||cb<0){ 101 flag=1; 102 } 103 r[i]=new Rectangle(db,cb); 104 zh=zh+r[i].getArea(); 105 he[gs]=r[i].getArea(); 106 gs++; 107 } 108 for(i=0;i ){ 109 double a; 110 double b; 111 double d; 112 double[] three=new double[3]; 113 three[0]=x.nextDouble();three[1]=x.nextDouble();three[2]=x.nextDouble(); 114 Arrays.sort(three); 115 a=three[0];b=three[1];d=three[2]; 116 if(a<0||b<0||d<0||a+b<=d){ 117 flag=1; 118 } 119 t[i]=new Triangle(a,b,d); 120 zh=zh+t[i].getArea(); 121 he[gs]=t[i].getArea(); 122 gs++; 123 } 124 if(flag==1){ 125 System.out.println("Wrong Format"); 126 System.exit(0); 127 } 128 System.out.println("Original area:"); 129 for (i=0;i ){ 130 System.out.printf("%.2f ",he[i]); 131 } 132 System.out.printf("\nSum of area:%.2f\n",zh); 133 System.out.println("Sorted area:"); 134 Arrays.sort(he); 135 for(i=0;i ){ 136 System.out.printf("%.2f ",he[i]); 137 } 138 System.out.printf("\nSum of area:%.2f",zh); 139 } 140 }
7-6 实现图形接口及多态性 (30 分)
编写程序,使用接口及类实现多态性,类图结构如下所示:
其中:
- GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
- Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
- 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)
输入格式:
从键盘分别输入圆的半径值及矩形的宽、长的值,用空格分开。
输出格式:
- 如果输入的圆的半径值及矩形的宽、长的值非法(≤0),则输出
Wrong Format
- 如果输入合法,则分别输出圆的面积和矩形的面积值(各占一行),保留两位小数。
1 import java.util.*; 2 class Shape{ 3 public double getArea(){ 4 return 0.0; 5 } 6 } 7 class Circle extends Shape{ 8 private double radius; 9 public double getArea(){ 10 return Math.PI*radius*radius; 11 } 12 public double getradius(){ 13 return radius; 14 } 15 public void setradius(double radius){ 16 this.radius=radius; 17 } 18 } 19 class Rectangle extends Shape{ 20 private double width; 21 private double length; 22 public double getArea(){ 23 return width*length; 24 } 25 public double getwidth(){ 26 return width; 27 } 28 public void setwidth(double width){ 29 this.width=width; 30 } 31 public double getlength(){ 32 return length; 33 } 34 public void setlength(double length){ 35 this.length=length; 36 } 37 } 38 public class Main{ 39 public static void main(String[] args){ 40 Scanner cin=new Scanner(System.in); 41 double radius=cin.nextDouble(); 42 double width=cin.nextDouble(); 43 double length=cin.nextDouble(); 44 if(radius<=0||width<=0||length<=0) 45 System.out.println("Wrong Format"); 46 else{ 47 Circle a=new Circle(); 48 a.setradius(radius); 49 System.out.printf("%.2f\n",a.getArea()); 50 Rectangle c=new Rectangle(); 51 c.setwidth(width); 52 c.setlength(length); 53 System.out.printf("%.2f\n",c.getArea()); 54 } 55 } 56 }
总的来说三道题当时偷摸直接copy自己的码然后没怎么管类图就过了,但是写的还是有些不一样的。从题目给的图上分析来看,第一题就是渐进式的继承,第二题则要求采用实体类构建,抽象类定义,让其全部继承于Shape,第三题则要求使用getArea的接口来实现不同类使用相同方法。分析SourceMonitor给出的图可以看出这个自己写的版本相差不是很大,估计完全按题目写出来应该差很多的,然后第三题直接小而简了,使用接口的话估计复杂度会更低,下次还是要尽量更贴近题目写。
③对三次题目集中用到的正则表达式技术的分析总结
总的来最简单的应该是题目集6的题目了,这几道正则的题都是简单的字符串的匹配校验问题,使用单一的matches即可完成,只要内部的匹配写好了就没什么问题了。题目集4的水文数据校验及处理这个题则需要先对数据进行分割处理再匹配校验,但是当时那会对于正则还不是很熟悉,所以没能完成得比较好,题目集5的统计Java程序中关键词的出现次数这道题则一开始完全没什么头绪,当时写的时候时间也比较紧,也没怎么仔细研究,在网上看其他人写的代码时也是疑问颇多,不过后续尽量都去探究理解了,下一次会自己尽力去做。
④题目集5(7-4)中Java集合框架应用的分析总结
7-4 统计Java程序中关键词的出现次数 (25 分)编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit
行作为结束标志
输出格式:
- 当未输入源码时,程序输出
Wrong Format
- 当没有统计数据时,输出为空
- 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为
数量\t关键字
1 import java.util.*; 2 import java.util.regex.Matcher; 3 import java.util.regex.Pattern; 4 public class Main { 5 public static void main(String[] args) { 6 Scanner input=new Scanner(System.in); 7 String a; 8 StringBuilder ss=new StringBuilder(); 9 Mapmap=new HashMap (); 10 String []key= { "abstract","assert","boolean","break","byte","case","catch", 11 "char","class","const","continue","default","do","double","else", 12 "enum","extends","false","final","finally","float", 13 "for","goto","if","implements","import","instanceof", 14 "int","interface","long","native","new","null","package", 15 "private","protected","public","return","short","static", 16 "strictfp","super","switch","synchronized","this","throw", 17 "throws","transient","true","try","void","volatile","while" 18 }; 19 int j=0; 20 for(int i=0;;i++) { 21 for(j=0;;j++) { 22 if(j==0) 23 break; 24 } 25 if(i==0) 26 break; 27 } 28 for(int i=0;;i++) { 29 a = input.nextLine(); 30 if (a.equals("exit")) 31 break; 32 if (a.matches("(.*)//(.*)")) { 33 String b[] = a.split("//"); 34 ss.append(b[0] + " "); 35 } else 36 ss.append(a + " "); 37 } 38 int count=0; 39 String s=ss.toString(); 40 Pattern p=Pattern.compile("\"(.*?)\""); 41 Matcher m=p.matcher(s); 42 while(m.find()){ 43 s=s.replace(m.group()," "); 44 p=Pattern.compile("\"(.*?)\""); 45 m=p.matcher(s); 46 } 47 p=Pattern.compile("/\\**(.*?)/"); 48 m=p.matcher(s); 49 while(m.find()){ 50 s=s.replace(m.group()," "); 51 m=p.matcher(s); 52 } 53 if(s.isEmpty()) 54 {System.out.println("Wrong Format"); 55 System.exit(0); 56 } 57 s=s.replace("["," "); 58 s=s.replace("]"," "); 59 s=s.replace("-","a"); 60 s=s.replace("*","a"); 61 s=s.replace("/","a"); 62 s=s.replace("+","a"); 63 s=s.replace(">","a"); 64 s=s.replace("=","a"); 65 s=s.replace("!","a"); 66 s=s.replace(":","a"); 67 s=s.replace("\\","a"); 68 s= s.replaceAll("[^a-zA-Z]", " "); 69 String []s1=s.split("[ ' ']"); 70 for(int i=0;i ) { 71 for (j = 0; j < key.length; j++) { 72 if (s1[i].equals(key[j])) 73 map.put(key[j], 0); 74 } 75 } 76 for( int i = 0;i ) { 77 for (j = 0; j < key.length; j++) { 78 if (s1[i].equals(key[j])) { 79 count = map.get(key[j]); 80 map.put(key[j], count + 1); 81 } 82 } 83 } 84 Set set=map.keySet(); 85 Object[] arr=set.toArray(); 86 Arrays.sort(arr); 87 for(Object k:arr){ 88 System.out.println(map.get(k)+"\t"+k); 89 } 90 } 91 }
对于这份代码的理解上来看,在集合框架应用上应该是使用了Map这个接口,里面的元素键与值成对存在,让存储了关键词的字符串与设定好的值进行一个映射来解决问题。
分析SourceMonitor给出的图也可看出这份代码各方面都很简洁,效率很高。
采坑心得:
1.分析的除了系列对比来说的每个题都是比较难,困住当时的我的,基本上都花费了很多时间,解决与否尚且不论,但是这几个题基本上考察完全了类与类之间的关系和语法,只能说掌握的算不上很好,需要继续夯实;
2.正则方面的题目经过之前的题目集只是对基础有了了解,这次也可以看出在题目集6中的答题都完成的很快,但是对于4、5中的难一些的题目都没能了解更多,对于这方面的内容还是急需加强;
3.吃了时间的亏,提前开始对题目的解答,让时间不那么紧迫,更多地在答题时去吸收题目中的知识。
改进建议:
还是希望很难或者需要自学内容的题目都能进行一个由易到难的引导,这次的正则跳度太大,最后一次题目集反而是最简单的,希望能调整一下,给学习没有很好的同学一个适应的机会,除此之外,其他的都挺好的,没有什么别的建议了。
总结:
对于本阶段三次题目集的学习,还是学到了很多东西,对于封装的熟悉,对于类与类之间关系和方法都更熟练了,对于多态接口等方面也有一定的了解了,继续进行了正则表达式的学习,对于简单的题目把握比较大了,难题也会继续加深学习,代码能力确实是需要自己梳理编写才能得到切实的提高,对于正则这方面的编码能力还有待提高。对于课程工作的建议上面也写到了,其他地方应该没有别的建议了,感觉现在的课上氛围和课下的练习检查以及作业什么的都挺好的。