oop第二次总结分析作业
一、前言
通过这三次题目集分析,题量相比之前有明显的增加,但总体上难度有所下调,有两道题我还没完全拿到满分,其中有题完全没思路,这两题用到的知识点都有关正则表达式。此外,题目集考查的知识点还有聚合、封装、继承、多态、接口。
二、设计与分析
1.题目集4(7-2)与题目集5(7-5)两种日期聚合类设计的优劣比较:
① 相比于题目集4,题目集5的设计可拓展性更强,具有较强的可延伸性;
② 题目集4的类连续调用来实现功能,通过DateUtil类调用Date类,Date类调用Day类,Date类调用Day类,Day类调用Month类,Month类调用Year,结构相对冗杂,类的调用较为繁琐;
③再者,题集4代码书写复杂程度高,不够简洁明了,只实现了一个类与类间的调用。
两题类图对比如下:
7-5:
7-4:
2.题目集4(7-3)题目集6(7-5、7-6)三种渐进式图形继承的设计思路与技术运用(封装、继承、多态、接口):
①尽量使代码可复用,例如使用this及super关键字
②构造方法链可以调用重载的构造方法或父类的构造方法;
③一个类可以实现多个接口,但是只能继承一个类;
④重写方法使用标注@Override;
⑤继承用于设计一些有共性的类来避免冗余并使系统易于理解和易于维护。
7-5题目代码、类图及表内容展示:
输入格式:
有三种输入方式(以输入的第一个数字划分[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:值
7-5源码如下:
import java.util.Scanner; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int circle_amount = input.nextInt(); int rectangle_amount = input.nextInt(); int triangle_amount = input.nextInt(); if (circle_amount>=0&&triangle_amount>=0&&rectangle_amount>=0) { Circle c[] = new Circle[circle_amount]; Rectangle r[] = new Rectangle[rectangle_amount]; Triangle t[] = new Triangle[triangle_amount]; ArrayList <Double> area=new ArrayList<Double>(); for (int i = 0; i < circle_amount; i++) { c[i] = new Circle(input.nextDouble()); if (!c[i].validate()) { System.out.println("Wrong Format"); return ; } area.add(c[i].getArea()); } for (int i = 0; i < rectangle_amount; i++) { r[i] = new Rectangle(input.nextDouble(),input.nextDouble()); if (!r[i].validate()) { System.out.println("Wrong Format"); return ; } area.add(r[i].getArea()); } for (int i = 0; i <triangle_amount; i++) { t[i] = new Triangle(input.nextDouble(), input.nextDouble(), input.nextDouble()); //System.out.println("Wrong Format"); if (t[i].validate()==false) { System.out.println("Wrong Format"); return ; } area.add(t[i].getArea()); } System.out.println("Original area:"); allArea(area); System.out.printf("Sum of area:%.2f\n",sumArea(area)); Collections.sort(area); System.out.println("Sorted area:"); for(double i:area) { System.out.printf("%.2f ",i); } System.out.println(); System.out.printf("Sum of area:%.2f\n",sumArea(area)); } else { System.out.println("Wrong Format"); } } public static double sumArea(ArrayList <Double>area){ double s = 0; for (double i:area) s=s+i; return s; } public static void allArea(ArrayList <Double> area) { for (double i:area) System.out.printf("%.2f ",i); System.out.println(); } } abstract class Shape{ public abstract double getArea(); public abstract boolean validate(); public String toString() { return ""; } } class Circle extends Shape{ double ridious; public Circle() {} public boolean validate() { if(ridious>0) { return true; }else { return false; } } public Circle(double ridious) { //super(); this.ridious = ridious; } public double getArea(){ return Math.PI*ridious*ridious; } } class Rectangle extends Shape{ double width,length; public Rectangle() {} public boolean validate() { if(width>0&&length>0) return true; else return false; } public Rectangle(double length,double width) { //super(); this.length =length; this.width=width; } public double getArea(){ return length*width; } } class Triangle extends Shape{ double a,b,c; public Triangle() {} public Triangle(double a, double b, double c) { //super(); this.a = a; this.b = b; this.c = c; } public double getArea(){ double s=0,area=0; s=(a + b + c)/2; area = Math.sqrt(s*(s-a)*(s-b)*(s-c)); return area; } public boolean validate() { if (a+b>c&&a+c>b&&b+c>a) return true; else return false; } }


7-6(接口及类实现多态性):
输入格式:
从键盘分别输入圆的半径值及矩形的宽、长的值,用空格分开。
输出格式:
- 如果输入的圆的半径值及矩形的宽、长的值非法(≤0),则输出
Wrong Format - 如果输入合法,则分别输出圆的面积和矩形的面积值(各占一行),保留两位小数。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); double radius=input.nextDouble(); double width=input.nextDouble(); double length=input.nextDouble(); if(radius>0&&width>0&&length>0) { Circle c=new Circle(radius); Rectangle r=new Rectangle(width,length); System.out.printf("%.2f\n",c.getArea()); System.out.printf("%.2f",r.getArea()); } else System.out.println("Wrong Format"); } } interface GetArea{ public abstract double getArea(); } class Circle implements GetArea{ double radius; Circle(){} Circle(double radius){ this.radius=radius; } public double getArea(){ double s=Math.PI*radius*radius; return s; } public void setRadius(double radius) { this.radius=radius; } public double getRadius() { return radius; } } class Rectangle implements GetArea{ double width,length; Rectangle(){} Rectangle(double width,double length){ this.width=width; this.length=length; } public double getArea(){ double s=width*length; return s; } public void setWidth(double width) { this.width=width; } public double getWidth() { return width; } public void setLength(double length) { this.length=length; } public double getLength() { return length; } }
表内容:
3.正则表达式技术的分析:
①对于庞大的数据,正则表达式可以帮助我们过滤不需要的,匹配需要的数据,通常被用来检索、替换那些符合某个模式(规则)的文本;
②题目集4中的水文数据处理及校验需要对正则表达式的匹配非常熟练,会简单的分割处理,再对每行输入的数据用正则表达式再匹配处理;
③正则表达式的应用十分广泛,如:匹配格式正确的QQ号、手机号、验证码等.
4.题目集5(7-4)中JAVA集合框架应用的总结分析:
数组存储数据有较多的弊端,而Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组。
Collection接口:单列数据,定义了存取一组对象的方法的集合 List:元素有序、可重复的集合 Set:元素无序、不可重复的集合
Map接口:双列数据,保存具有映射关系“key-value对”的集合
设计思路:将输入的内容利用StringBuilder连接起来作为一个整体,再利用正则表达式对整体进行查找匹配、校检等操作。这里主要谈谈Java中所提供的集合框架(类似c++中stl),这里使用Map更加方便储存关键词出现次数,键用String类型,值用int类型。另外,在java中,集合框架是围绕一组标准接口而设计,提供了许多有用的接口、数据结构和算法等,功能十分强大,合理使用有利于提升对数据的功能实现的高效性。
三、踩坑心得
1. 就我而言,水文处理题目集有较大的疑问和困难,首先要通过正则表达式分割每行输入的数据,再对每行数据分块处理,处理方式同样为正则表达式匹配,数据的输出也要格式规范,个人觉得也是本题难度较大的地方,对if语句和输出语句的运用要求较高,逻辑也要十分清晰,当时就一直卡在输出语句的规范问题上,在题目截至和才又想通一个测试点,虽然感觉可惜,但也是对我的一种鞭策,下次写题不能再拖拉。以下是我的部分源码:
import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main{ public static void main(String[] args) { Scanner input=new Scanner(System.in); /*String regex="([1-9]\\d{0,3}/([1-9])|1[0-2])/(([1-9])|([1-2]\\d)|(3[0-1]))\\s([02468])|1([02468])|(2[02]):00\\|" + "(([1-9]\\d{0,2})|1000)([\\.\\d{0,3}])?\\|(([1-9]\\d{0,2})|1000)([\\.\\d{0,3}])?\\|" + "([1-9]\\.\\d{2})/([1-9]\\.\\d{2})\\|"+"(([1-9]\\d{0,2})|1000)([\\.\\d{0,3}])?";*/ String regex1="([1-9]\\d{0,3})/(([1-9])|(1[0-2]))/(([1-9])|([1-2]\\d)|(3[0-1])) (([02468])|(1[02468])|(2[02])|0):00"; String regex2="[1-9]\\d{0,2}(\\.\\d{0,3})?"; String regex3="[1-9]\\d{0,2}(\\.\\d{0,3})?"; String regex4="([1-9]\\.\\d{2})/([1-9]\\.\\d{2})"; String regex6="[1-9]\\.\\d{2}"; String regex5="[1-9]\\d{0,2}(\\.\\d{0,3})?"; String regex="(\\s)+"; int i=0,cnt=0,cnt1=0; String []row=new String[1000]; String []s=new String[1000]; String []a=new String[1000]; String []data=new String[100]; char []c=new char[1000]; double max=0; int h=0; int g[]=new int[10]; //System.out.println(); row[i]=input.nextLine(); while(!row[i].equals("exit")) {//字符串数组获取每行的输入 i++; row[i]=input.nextLine(); } boolean bl=Pattern.matches(regex,row[0]); if(row[0].equals("exit")||bl==true||(row[0].equals(""))) {//无输入 System.out.println("Max Actual Water Level:0.00"); System.out.println("Total Water Flow:0.00"); } else { for(int j=0;j<i;j++) { row[j]=row[j].trim(); cnt=0; for(int k=0;k<row[j].length();k++) { c[k]= row[j].charAt(k); s[k]=c[k]+""; if(s[k].equals("|")) cnt++; } if(cnt==4) { data=row[j].split("\\|");//将每行数据分割成五部分 boolean bl1=Pattern.matches(regex1,data[0]); boolean bl2=Pattern.matches(regex2,data[1]); boolean bl3=Pattern.matches(regex3,data[2]); boolean bl4=Pattern.matches(regex4,data[3]); boolean bl5=Pattern.matches(regex5,data[4]); //boolean bl6=Pattern.matches(regex6,row[j]); if(bl1==true) { /*Pattern pattern = Pattern.compile(regex2); Matcher matcher=pattern.matcher(row[j]);*/ } else { System.out.printf("Row:%d,Column:1Wrong Format\n",j+1); } if(bl2==true) { } else { System.out.printf("Row:%d,Column:2Wrong Format\n",j+1); } if(bl3==true) { } else { System.out.printf("Row:%d,Column:3Wrong Format\n",j+1); } if(bl4==true) { } else { //double []b=new double[10]; String []e=new String[100]; e=data[3].split("/"); boolean bl6=Pattern.matches(regex6,e[0]); if(bl6==false) System.out.println("Row:"+(j+1)+",Column:4Wrong Format"); boolean bl7=Pattern.matches(regex6,e[1]); if(bl7==false) System.out.println("Row:"+(j+1)+",Column:5Wrong Format"); } if(bl1==bl2==bl3==bl4==bl5==true) { double []b=new double[10]; a=data[3].split("/"); b[0]=Double.parseDouble(a[0]); b[1]=Double.parseDouble(a[1]); for(h=0;h<i;h++) if(b[1]>b[0]) { g[h]=j+1; //System.out.printf("Row:%d GateOpening Warning",j+1); } cnt1++; } if(bl5==true) { //double max=0; double level[]=new double[10]; level[j]=Double.parseDouble(data[4]); if(max<level[j]) max=level[j]; // System.out.println("Max Actual Level:"+max); } else { System.out.println("Row:"+(j+1)+",Column:6Wrong Format"); } if(bl1==false||bl2==false||bl3==false||bl4==false||bl5==false) System.out.println("Data:"+row[j]); if(cnt1==i) { System.out.print(cnt1); for( h=0;h<i;h++) System.out.printf("Row:%d GateOpening Warning\n",g[h]); System.out.println("Max Actual Level:"+max); } } else { System.out.println("Wrong Format"); System.out.println(row[j]); } } } }
四、改进建议
1.为使设计清晰,内聚性、一致性和封装性都是好的设计原则,类应该有一个很清晰的合约,从而易于解释和易于通解。
2.类是为许多不同用户的使用而设计的为了能在大范围应用中使用,一个类应该通过属性和方法提供和方法提供各种自定义功能的实现方式。
3.接口和抽象类都可以用为对象指定共同的行为,接口比抽象类更加灵活。
五、总结
1.自学能力有待提高,题集中很多老师没讲到或没讲全的内容都需要自己找资料学习;
2.题目较难没思路时应该及时百度找资源自学,或者向会的人请教,死磕只会浪费时间和精力;
3.多看书多学习多练题目多思考,日复一日、必有精进。

浙公网安备 33010602011771号