学习OO第二阶段总结
(1)前言:
对java第二阶段所做PTA的4~6题目集进行总结与分析。
第四个题目集的题量虽小,但每道题都非常高,尤其是第一题的水文数据校验及处理,十分考验对正则表达式的使用,后两题相当于把前面日期类的设计给聚合了,并且涉及了继承的知识,总体花费时间较长。
第五个题目集,第一题依然是日期类的聚合设计题目,但是题目给出的类图有所区别,是把dateutil这个类作为了父类,实现功能的过程中会使用Year、Month、Day类中的方法,第二题是该题目集难度最大的一道题,也是主要考验对Matcher类和Pattern类的方法的使用和对String方法的使用,第三题和第四题是比较偏基础的数组排序和合并问题,难度不是很大。
第六个题目集,前四小题都是正则表达式的基础训练,如果熟练掌握正则表达式的使用的话,做这四道题所花时间不会太长,第五题依旧是图形的继承不过多了一个多态,解决难度不是很大,只要在之前的基础上加上一个类数组就可以了,第六题依旧是图形类问题但是要求把getarea方法写成一个接口。总的来说第六个题目集的难度相对较低,所花时间较少。
(2)设计与分析:
题目集4(7-2)和题目集5(7-4)的比较分析:
就两题给出的类设计图来看
很明显,题目集4中的四个类没有很强的关联性,而且重复写了一些方法和属性,在书写的时候极为繁琐,而题目集5中的类聚合设计就将year、month、day的值都写为value,并且他们都继承于父类dateutil,这样设计的时候他们就会拥有公有的属性和方法,写代码的时候也会少花一些时间来重复步骤,这里属于是良好的运用了java语言继承与多态的特性。并且两者都做到了封装,即主程序里只使用了dateutil类的方法,将其中使用其他三个子类的细节隐藏封装了起来,这样安全性更高,用户使用起来也易于理解,体验感也更好。
import java.time.LocalDate; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner sc=new Scanner(System.in); int choice=sc.nextInt(); int y,m,d; int y1,m1,d1; int y2,m2,d2; if(choice<1||choice>3) { System.out.println("Wrong Format"); return; } switch(choice) { case 1:y=sc.nextInt(); m=sc.nextInt(); d=sc.nextInt(); DateUtil date=new DateUtil(d,m,y); if(date.checkInputValidity()==false) { System.out.println("Wrong Format"); return; } System.out.println(date.getNextNDays(sc.nextInt()).showDate()); break; case 2:y=sc.nextInt(); m=sc.nextInt(); d=sc.nextInt(); DateUtil date1=new DateUtil(d,m,y); if(date1.checkInputValidity()==false) { System.out.println("Wrong Format"); return; } System.out.println(date1.getPreviousNDays(sc.nextInt()).showDate()); break; case 3:y1=sc.nextInt();m1=sc.nextInt();d1=sc.nextInt(); y2=sc.nextInt();m2=sc.nextInt();d2=sc.nextInt(); DateUtil S1=new DateUtil(d1,m1,y1); DateUtil S2=new DateUtil(d2,m2,y2); if(S1.checkInputValidity()==false||S2.checkInputValidity()==false) { System.out.println("Wrong Format"); return; } System.out.println(S1.getDaysofDates(S2)); break; } } } class Day{ int value; Month month=new Month(); int[] mon_maxnum=new int[] {0,31,28,31,30,31,30,31,31,30,31,30,31}; public Day() { } public Day(int yearValue,int monthValue,int dayValue) { this.value=dayValue; this.month.value=monthValue; this.month.year.value=yearValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Month getMonth() { return month; } public void setMonth(Month month) { this.month = month; } void resetMin() { this.value=1; } void resetMax() { this.value=this.mon_maxnum[this.month.value]; } boolean validate() { if(this.month.year.isLeapYear()==true) this.mon_maxnum[2]=29; else this.mon_maxnum[2]=28; if(this.value>=1&&this.value<=this.mon_maxnum[this.month.value]) { return true; } else return false; } void dayIncrement() { if(this.value==this.mon_maxnum[this.month.value]) this.value=1; else this.value++; } void dayReduction() { if(this.value==1) this.value=this.mon_maxnum[this.month.value-1]; else this.value--; } } class Month{ int value; Year year=new Year(); public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } public Month() { } public Month(int yearValue,int monthValue) { this.value=monthValue; this.year.value=yearValue; } void resetMin() { this.value=1; } void resetMax() { this.value=12; } boolean validate() { if(this.value>=1&&this.value<=12) return true; else return false; } void monthIncrement() { if(this.value==12) this.resetMin(); else this.value++; } void monthReduction() { if(this.value==1) this.resetMax(); else this.value--; } } class DateUtil{ Day day=new Day(); public void setDay(Day day) { this.day = day; } public DateUtil() { } public DateUtil(int d,int m,int y) { this.day.value=d; this.day.month.value=m; this.day.month.year.value=y; } Day getDay() { return this.day; } boolean checkInputValidity() { if(this.day.month.year.validate()==true&&this.day.month.validate()==true&&this.day.validate()==true) return true; else return false; } boolean compareDates(DateUtil date) { if(this.day.month.year.value>date.day.month.year.value) return true; else if(this.day.month.year.value<date.day.month.year.value) return false; else if(this.day.month.value>date.day.month.value) return true; else if(this.day.month.value<date.day.month.value) return false; else if(this.day.value>date.day.value) return true; else if(this.day.value<date.day.value) return false; else return false; } boolean equalTwoDates(DateUtil date) { if(this.day.month.year.value==date.day.month.year.value&&this.day.month.value==date.day.month.value&&this.day.value==date.day.value) return true; else return false; } String showDate() { return this.day.month.year.value+"-"+this.day.month.value+"-"+this.day.value; } DateUtil getNextNDays(int n){ LocalDate a=LocalDate.of(this.day.month.year.value, this.day.month.value, this.day.value); a=a.plusDays(n); this.day.month.year.value=a.getYear(); this.day.month.value=a.getMonthValue(); this.day.value=a.getDayOfMonth(); return new DateUtil(this.day.value,this.day.month.value,this.day.month.year.value); } DateUtil getPreviousNDays(int n) { LocalDate a=LocalDate.of(this.day.month.year.value, this.day.month.value, this.day.value); a=a.plusDays(n*(-1)); this.day.month.year.value=a.getYear(); this.day.month.value=a.getMonthValue(); this.day.value=a.getDayOfMonth(); return new DateUtil(this.day.value,this.day.month.value,this.day.month.year.value); } int getDaysofDates(DateUtil date) { LocalDate a=LocalDate.of(this.day.month.year.value, this.day.month.value, this.day.value); LocalDate b=LocalDate.of(date.day.month.year.value, date.day.month.value, date.day.value); return Math.abs((int) (a.toEpochDay()-b.toEpochDay())); } } class Year{ int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Year() { } public Year(int value) { this.value=value; } boolean isLeapYear() { if((this.value%4==0&&this.value%100!=0)||this.value%400==0) { return true; } else return false; } boolean validate() { if(this.value>=1900&&this.value<=2050) return true; else return false; } void yearIncrement() { this.value++; } void yearReduction() { this.value--; } }
import java.time.LocalDate; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner sc=new Scanner(System.in); int choice=sc.nextInt(); int y,m,d; int y1,m1,d1; int y2,m2,d2; int next,previous; if(choice<1||choice>3) { System.out.println("Wrong Format"); return; } switch(choice) { case 1:y=sc.nextInt(); m=sc.nextInt(); d=sc.nextInt(); DateUtil date=new DateUtil(d,m,y); if(date.checkInputValidity()==false) { System.out.println("Wrong Format"); return; } next=sc.nextInt(); System.out.println(date.showDate()+" next "+next+" days is:"+date.getNextNDays(next).showDate()); break; case 2:y=sc.nextInt(); m=sc.nextInt(); d=sc.nextInt(); DateUtil date1=new DateUtil(d,m,y); if(date1.checkInputValidity()==false) { System.out.println("Wrong Format"); return; } previous=sc.nextInt(); System.out.println(date1.showDate()+" previous "+previous+" days is:"+date1.getPreviousNDays(previous).showDate()); break; case 3:y1=sc.nextInt();m1=sc.nextInt();d1=sc.nextInt(); y2=sc.nextInt();m2=sc.nextInt();d2=sc.nextInt(); DateUtil S1=new DateUtil(d1,m1,y1); DateUtil S2=new DateUtil(d2,m2,y2); if(S1.checkInputValidity()==false||S2.checkInputValidity()==false) { System.out.println("Wrong Format"); return; } System.out.println("The days between "+S1.showDate()+" and "+S2.showDate()+" are:"+S1.getDaysofDates(S2)); break; } } } class Day{ int value; Month month=new Month(); int[] mon_maxnum=new int[] {0,31,28,31,30,31,30,31,31,30,31,30,31}; public Day() { } public Day(int yearValue,int monthValue,int dayValue) { this.value=dayValue; this.month.value=monthValue; this.month.year.value=yearValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Month getMonth() { return month; } public void setMonth(Month month) { this.month = month; } void resetMin() { this.value=1; } void resetMax() { this.value=this.mon_maxnum[this.month.value]; } boolean validate() { if(this.month.year.isLeapYear()==true) this.mon_maxnum[2]=29; else this.mon_maxnum[2]=28; if(this.value>=1&&this.value<=this.mon_maxnum[this.month.value]) { return true; } else return false; } void dayIncrement() { if(this.value==this.mon_maxnum[this.month.value]) this.value=1; else this.value++; } void dayReduction() { if(this.value==1) this.value=this.mon_maxnum[this.month.value-1]; else this.value--; } } class Month{ int value; Year year=new Year(); public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } public Month() { } public Month(int yearValue,int monthValue) { this.value=monthValue; this.year.value=yearValue; } void resetMin() { this.value=1; } void resetMax() { this.value=12; } boolean validate() { if(this.value>=1&&this.value<=12) return true; else return false; } void monthIncrement() { if(this.value==12) this.resetMin(); else this.value++; } void monthReduction() { if(this.value==1) this.resetMax(); else this.value--; } } class DateUtil{ Day day=new Day(); public void setDay(Day day) { this.day = day; } public DateUtil() { } public DateUtil(int d,int m,int y) { this.day.value=d; this.day.month.value=m; this.day.month.year.value=y; } Day getDay() { return this.day; } boolean checkInputValidity() { if(this.day.month.year.validate()==true&&this.day.month.validate()==true&&this.day.validate()==true) return true; else return false; } boolean compareDates(DateUtil date) { if(this.day.month.year.value>date.day.month.year.value) return true; else if(this.day.month.year.value<date.day.month.year.value) return false; else if(this.day.month.value>date.day.month.value) return true; else if(this.day.month.value<date.day.month.value) return false; else if(this.day.value>date.day.value) return true; else if(this.day.value<date.day.value) return false; else return false; } boolean equalTwoDates(DateUtil date) { if(this.day.month.year.value==date.day.month.year.value&&this.day.month.value==date.day.month.value&&this.day.value==date.day.value) return true; else return false; } String showDate() { return this.day.month.year.value+"-"+this.day.month.value+"-"+this.day.value; } DateUtil getNextNDays(int n){ LocalDate a=LocalDate.of(this.day.month.year.value, this.day.month.value, this.day.value); a=a.plusDays(n); this.day.month.year.value=a.getYear(); this.day.month.value=a.getMonthValue(); this.day.value=a.getDayOfMonth(); return new DateUtil(this.day.value,this.day.month.value,this.day.month.year.value); } DateUtil getPreviousNDays(int n) { LocalDate a=LocalDate.of(this.day.month.year.value, this.day.month.value, this.day.value); a=a.plusDays(n*(-1)); this.day.month.year.value=a.getYear(); this.day.month.value=a.getMonthValue(); this.day.value=a.getDayOfMonth(); return new DateUtil(this.day.value,this.day.month.value,this.day.month.year.value); } int getDaysofDates(DateUtil date) { LocalDate a=LocalDate.of(this.day.month.year.value, this.day.month.value, this.day.value); LocalDate b=LocalDate.of(date.day.month.year.value, date.day.month.value, date.day.value); return Math.abs((int) (a.toEpochDay()-b.toEpochDay())); } } class Year{ int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Year() { } public Year(int value) { this.value=value; } boolean isLeapYear() { if((this.value%4==0&&this.value%100!=0)||this.value%400==0) { return true; } else return false; } boolean validate() { if(this.value>=1820&&this.value<=2020) return true; else return false; } void yearIncrement() { this.value++; } void yearReduction() { this.value--; } }
三道图形继承类题目的比较分析:
这三题的前两题,我认为虽然都是使用了子类继承父类,虽然三种图形类拥有同名的方法,但是由于图形的特殊性,三种图形类并没有公共属性,并且每个方法在子类里都需要重写,所以在这样的设计里,使用继承的优势并不明显,但在第三题的设计中,通过接口设计getarea方法很好地实现了多态的特性,将题目最核心的需求求面积设计为接口方法,使得每种图形都能通过该接口求面积,可以说很好的解决了这一问题。
import java.util.Scanner; import java.text.DecimalFormat; public class Main{ public static void main(String [] args ) { Scanner sc=new Scanner(System.in); double r,s,t; DecimalFormat df = new DecimalFormat("######0.00"); int x=sc.nextInt(); if(x!=1&&x!=2&&x!=3&&x!=4) { System.out.println("Wrong Format"); return; } switch(x) { case 1: r=sc.nextDouble(); if(r<=0) {System.out.println("Wrong Format");return;} Circle circle=new Circle(); circle.setRadius(r); if(circle.check()==false) { System.out.println("Wrong Format"); return; } System.out.println("Circle's area:"+df.format(circle.getArea())); break; case 2:r=sc.nextDouble();s=sc.nextDouble(); if(r<=0||s<=0) {System.out.println("Wrong Format");return;} Rectangle rectangle=new Rectangle(); rectangle.setWidth(r); rectangle.setLength(s); if(rectangle.check()==false) { System.out.println("Wrong Format"); return; } System.out.println("Rectangle's area:"+df.format(rectangle.getArea())); break; case 3: r=sc.nextDouble(); if(r<=0) {System.out.println("Wrong Format");return;} Ball ball=new Ball(); ball.setRadius(r); if(ball.check()==false) { System.out.println("Wrong Format"); return; } System.out.println("Ball's surface area:"+df.format(ball.getArea())); System.out.println("Ball's volume:"+df.format(ball.getVolume())); break; case 4:r=sc.nextDouble();s=sc.nextDouble();t=sc.nextDouble(); if(r<=0||s<=0||t<=0) {System.out.println("Wrong Format");return;} Box box=new Box(); box.setWidth(r); box.setLength(s); box.setHeight(t); if(box.check()==false) { System.out.println("Wrong Format"); return; } System.out.println("Box's surface area:"+df.format(box.getArea())); System.out.println("Box's volume:"+df.format(box.getVolume())); break; } } } class Shape{ public double getArea(){//求图形面积 return 0; } public Shape() { System.out.println("Constructing Shape"); } } class Circle extends Shape{ private double radius;//半径 public double getArea() { return this.radius*this.radius*Math.PI; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public Circle() { System.out.println("Constructing Circle"); } public boolean check() { if(this.radius<=0) return false; else return true; } } class Rectangle extends Shape{ private double width; private double length; public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getArea() { return this.length*this.width; } public Rectangle() { System.out.println("Constructing Rectangle"); } public boolean check() { if(this.length<=0||this.width<=0) return false; else return true; } } class Ball extends Circle{ public double getArea() { return 4*Math.PI*this.getRadius()*this.getRadius(); } public double getVolume() {//求球体积 double a=4; double b=3; double i=a/b; return i*Math.PI*Math.pow(this.getRadius(),3 ); } public Ball() { System.out.println("Constructing Ball"); } } class Box extends Rectangle{ public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } private double height; public double getArea() { return 2*this.getLength()*this.getWidth()+2*this.height*this.getLength()+2*this.height*this.getWidth(); } public double getVolume() { return this.height*this.getLength()*this.getWidth(); } public Box() { System.out.println("Constructing Box"); } public boolean check() { if(this.height<=0||this.getLength()<=0||this.getWidth()<=0) return false; else return true; } }
import java.util.Arrays; import java.util.Scanner; import java.text.DecimalFormat; public class Main{ public static void main(String [] args ) { Scanner sc=new Scanner(System.in); Circle circle=new Circle(); Rectangle rectangle=new Rectangle(); DecimalFormat df = new DecimalFormat("######0.00"); circle.setRadius(sc.nextDouble()); rectangle.setLength(sc.nextDouble()); rectangle.setWidth(sc.nextDouble()); if(circle.check()==false||rectangle.check()==false) { System.out.println("Wrong Format");return; } System.out.println(df.format(circle.getArea())); System.out.println(df.format(rectangle.getArea())); } } class Shape{ public double getArea(){//求图形面积 return 0; } } class Triangle{ public double getSide1() { return side1; } public void setSide1(double side1) { this.side1 = side1; } public double getSide2() { return side2; } public void setSide2(double side2) { this.side2 = side2; } public double getSide3() { return side3; } public void setSide3(double side3) { this.side3 = side3; } private double side1,side2,side3; public boolean check() { if(this.side1+this.side2<this.side3||this.side1+this.side3<this.side2||this.side2+this.side3<this.side1) return false; else return true; } public double getArea() { double s=(this.side1+this.side2+this.side3)/2; return Math.sqrt(s*(s-this.side1)*(s-this.side2)*(s-this.side3)); } } class Circle extends Shape{ private double radius;//半径 public double getArea() { return this.radius*this.radius*Math.PI; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public boolean check() { if(this.radius<=0) return false; else return true; } } class Rectangle extends Shape{ private double width; private double length; public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getArea() { return this.length*this.width; } public Rectangle() { } public boolean check() { if(this.length<=0||this.width<=0) return false; else return true; } } class Ball extends Circle{ public double getArea() { return 4*Math.PI*this.getRadius()*this.getRadius(); } public double getVolume() {//求球体积 double a=4; double b=3; double i=a/b; return i*Math.PI*Math.pow(this.getRadius(),3 ); } public Ball() { } } class Box extends Rectangle{ public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } private double height; public double getArea() { return 2*this.getLength()*this.getWidth()+2*this.height*this.getLength()+2*this.height*this.getWidth(); } public double getVolume() { return this.height*this.getLength()*this.getWidth(); } public Box() { System.out.println("Constructing Box"); } public boolean check() { if(this.height<=0||this.getLength()<=0||this.getWidth()<=0) return false; else return true; } }
import java.util.Arrays; import java.util.Scanner; import java.text.DecimalFormat; public class Main{ public static void main(String [] args ) { Scanner sc=new Scanner(System.in); Circle circle=new Circle(); Rectangle rectangle=new Rectangle(); DecimalFormat df = new DecimalFormat("######0.00"); circle.setRadius(sc.nextDouble()); rectangle.setLength(sc.nextDouble()); rectangle.setWidth(sc.nextDouble()); if(circle.check()==false||rectangle.check()==false) { System.out.println("Wrong Format");return; } System.out.println(df.format(circle.getArea())); System.out.println(df.format(rectangle.getArea())); } } class Shape{ public double getArea(){//求图形面积 return 0; } } class Triangle{ public double getSide1() { return side1; } public void setSide1(double side1) { this.side1 = side1; } public double getSide2() { return side2; } public void setSide2(double side2) { this.side2 = side2; } public double getSide3() { return side3; } public void setSide3(double side3) { this.side3 = side3; } private double side1,side2,side3; public boolean check() { if(this.side1+this.side2<this.side3||this.side1+this.side3<this.side2||this.side2+this.side3<this.side1) return false; else return true; } public double getArea() { double s=(this.side1+this.side2+this.side3)/2; return Math.sqrt(s*(s-this.side1)*(s-this.side2)*(s-this.side3)); } } class Circle extends Shape{ private double radius;//半径 public double getArea() { return this.radius*this.radius*Math.PI; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public boolean check() { if(this.radius<=0) return false; else return true; } } class Rectangle extends Shape{ private double width; private double length; public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getArea() { return this.length*this.width; } public Rectangle() { } public boolean check() { if(this.length<=0||this.width<=0) return false; else return true; } } class Ball extends Circle{ public double getArea() { return 4*Math.PI*this.getRadius()*this.getRadius(); } public double getVolume() {//求球体积 double a=4; double b=3; double i=a/b; return i*Math.PI*Math.pow(this.getRadius(),3 ); } public Ball() { } } class Box extends Rectangle{ public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } private double height; public double getArea() { return 2*this.getLength()*this.getWidth()+2*this.height*this.getLength()+2*this.height*this.getWidth(); } public double getVolume() { return this.height*this.getLength()*this.getWidth(); } public Box() { System.out.println("Constructing Box"); } public boolean check() { if(this.height<=0||this.getLength()<=0||this.getWidth()<=0) return false; else return true; } }
对三次题目集中用到的正则表达式技术的分析总结:
三次题目集种使用到正则表达式的题目主要是题目集4的水文数据校验及处理、题目集5种统计关键词次数略微使用了一点、以及题目集6中的四道极为基础的正则表达式训练题,所以这里重点分析水文数据校验及处理。
首先题目给出了比较复杂的格式要求及数据形式要求,导致所使用的正则表达式较为冗长并且对每个数据都要进行检验,以下是我所写的判断合法性的有包含正则表达式的函数:
public boolean validateMeasureDateTime(String measureDateTime) { if (measureDateTime.trim().matches("(?:((?:([1-9]([0-9]{0,3}))/((?:(([1-9]|(1[0-2]))/(?:([1-9]|([1-2][0-8])|19))))|(?:(([13578])|([1][02])(/31)))|(?:(([13-9]|1[02])/(29|30)))))(?:(?:( [02468]| 1[02468]| 2[02]|):00))))|" + "(?:((?:([48]|[2468][048]|[13579][26]))|((?:(([1-9]([0-9]?))?:(0[48]|[2468][048]|[13579][26])))|(?:([48]|[2468][048]|[13579][26])00))/2/29)(?:(?:( [02468]| 1[02468]| 2[02]|):00)))")) return true; else return false; } /** * 检查水位 * * @param WaterLevel * @return */ public boolean validateWaterLevel(String WaterLevel) { if (WaterLevel.trim().matches("(?:(?:(([1-9]([0-9]{0,2})))(?:((.[0-9]{1,3})?))))")) return true; else return false; } /** * 检查开度 * * @param GateOpening * @return */ public boolean validateGateOpening(String GateOpening) { // System.out.println(GateOpening); GateOpening = GateOpening.trim(); int i = GateOpening.indexOf("/"); String GateOpening1 = GateOpening.substring(0, i); //目标开度 String GateOpening2 = GateOpening.substring(i + 1, GateOpening.length()); //实际开度 if (GateOpening1.matches("(?:(([1-9])(?:(.[0-9]{2}))))") == false) { System.out.println("Row:" + this.row + ",Column:4Wrong Format"); } if (GateOpening2.matches("(?:(([1-9])(?:(.[0-9]{2}))))") == false) { System.out.println("Row:" + this.row + ",Column:5Wrong Format"); } if (GateOpening1.matches("(?:(([1-9])(?:(.[0-9]{2}))))") && GateOpening2.matches("(?:(([1-9])(?:(.[0-9]{2}))))")) { if (Float.parseFloat(GateOpening2) > Float.parseFloat(GateOpening1)) { System.out.println("Row:" + this.row + " GateOpening Warning"); } return true; } else return false; } /** * 检查流量合法性 * * @param Flow * @return */ public boolean waterFlow(String Flow) { if (Flow.trim().matches("(?:(?:(([1-9]([0-9]{0,2})))(?:((.[0-9]{1,3})?))))")) { return true; } else return false; }
题目集5(7-4)中Java集合框架应用的分析总结
本题的需求是统计用户输入的语句中关键词出现的次数,本题的设计思路主要是:先将将会出现的关键词全部存入一个String数组中,然后通过stringbuilder的append和replace方法将原语句中注释和字符串中的语句全部排除,然后通过for (String key : keyword) {
//在str字符串中匹配单词
Matcher m = Pattern.compile("\\b" + key + "\\b").matcher(str);
int cnt = 0;
while (m.find()) cnt++;//统计找到多少个
if (cnt != 0) map.put(key, cnt); //存入map中
}
可以实现循环求得每个关键词出现得次数,最后通过map遍历输出得到以升序排列输出的统计关键词及其个数。
import java.util.Iterator; import java.util.Map; import java.util.Scanner; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; // String[] keyword= {"abstract","assert","boolean","break","byte","case","catch","char", // "class","const","continue","default","do","double","else","enum","extends","false","final", // "finally","float","for","goto","if","implements","import","instanceof","int","interface", // "long","native","new","null","package","private","protected","public","return","short","static", // "strictfp","super","switch","synchronized","this","throw","throws","transient","true","try", // "void","volatile","while" // }; public class Main { //注释中的关键字:注释有行注释和段注释,都需要匹配、 //这里还需要考虑字符串中出现的注释符号,不能当作注释,还有字符串中如果出现转义的双引号,不能作为字符串的结束依据 //字符串中的关键字:双引号之间 //关键字升序可以用map解决,hashmap或者treemap public static void main(String[] args) { String[] keyword = {"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while" }; Scanner scanner = new Scanner(System.in); String s = new String(); StringBuilder sb = new StringBuilder(); while (!(s = scanner.nextLine()).equals("exit")) { sb.append(s.replaceAll("//.*", " ").replaceAll("\".*\"", " ") + " "); } //如果没有输入代码输出Wrong Format if (sb.length() == 0) { System.out.println("Wrong Format"); System.exit(0); } String str = sb.toString(); /*String[] pre = {"\\$", "_", "int\\(\\)", "boolean\\(\\)", "double\\(\\)", "float\\(\\)", "byte\\(\\)", "long\\(\\)", "short\\(\\)", "\\*"}; if (str.length() > 1210) { for (String a : pre) { str = str.replaceAll(a, " "); } }*/ str = str.replaceAll("/\\*\\s*.*\\s*\\*/", " ").replaceAll("[\\[|\\]][\\S]*", " ").replaceAll("[/][/][\\S\\s]*?\n", " ").replaceAll("[/][*][*][\\S\\s]*?[*][/]|[/][*][\\S\\s]*?[*][/]", " ").replaceAll("\"[\\S\\s]*?\"", " "); //找到关键字,然后插入map Map<String, Integer> map = new TreeMap<String, Integer>(); for (String key : keyword) { //在str字符串中匹配单词 Matcher m = Pattern.compile("\\b" + key + "\\b").matcher(str); int cnt = 0; while (m.find()) cnt++;//统计找到多少个 if (cnt != 0) map.put(key, cnt); //存入map中 } //遍历map然后输出 Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); System.out.println(entry.getValue() + "\t" + entry.getKey()); } } }
(3)踩坑心得:
在PTA的三次题目集中,所花时间最长的应该是题目集4,虽然题量较少,但每道题所花时间都较长。
但虽说略有难度,但相比上三次作业的坑点,我觉得坑点还是变少了的,唯一没满分的是题目集5的第二题统计关键词个数最后一个正常测试的测试点没过,所以只拿了98分,不知道是测试点设计的有问题还是我写的有问题,然后因为大面积的题目都是渐进式设计,主要目的应该是为了培养我们对面向对象语言的封装继承多态和接口的实现。
最后得到的结论就是:写java代码一定要多多利用继承多态接口,感觉真的蛮方便的。
(4)改进建议:
在做图形类继承多态及接口题目的时候,我并没有完全按照题目的意思,使用接口,而是为了图快,直接在上次作业的代码基础上做了修改,下次一定好好按照题目要求写。
对正则表达式技术的使用还是有所欠缺,要多多练习。
对基础类例如stringbuilder、matcher、pattern的方法使用还不够熟练,要要多多学习和练习熟练掌握。
对冒泡选择插入排序的知识有所遗忘,要多多温习以前的知识。
(5)总结:
经过六次题目集的练习,已经逐渐习惯了面向对象语言的编写和使用,每一次的题目集都有新的收获,在做题目的时候可以很快提升编写代码的能力,这三次题目集,让我对面向对象的封装继承多态三个特性有了全新的了解,并对面向对象的基本原则——“单一职责原则”和“开闭原则”有了一定的了解。
如何设计一个合理的类,让设计的多个类形成有机的链接,最终将程序的要求实现出来,这是我们编程中面临的问题。我们在写作业的时候,老师几乎都是在实验指导书中已经给好了类图,但是细想一下,如果老师没有给出类图,这题的难度可就不单单是翻倍而已了,它需要我们精心设计我们的类图,让程序实现。类的设计需要我们对程序中的内容逻辑清晰,把各个内容之间的关系合理的连接起来,并且要在保持代码的简洁性的情况下将类包设计出来,这对于我们初学者来说是一个很有难度的事情。
对老师及课程的建议:
最近几次课有一个很明显的感觉,就是感觉老师讲的东西不是很好消化,并且课上大部分时间都是老师一个人在讲,我们实践的时间也比较少。所以建议老师增强课堂上师生的互动,让同学们真正理解所讲的内容。
对作业、实验的建议:
作业量和实验难度目前来说适中,我不觉得有什么需要改进的。

浙公网安备 33010602011771号