PTA题目集4~6总结
前言:
题目集四:此次题目集四共有三题,题量较少但是题目难度及复杂度较大。第一题为水文数据校验及处理,本题主要考察正则表达式的使用及接口的使用,对正则表达式及接口使用要求较高,题目较复杂;第二题为日期问题面向对象聚合一,本题主要考察对类的封装,题目对get和set的运用较多,对this及super关键字的使用有一定的要求,题目总体较复杂;第三题为图形继承,本题主要考察java中的继承的使用,对方法的重写也有所考察,难度与复杂度相对一般。
题目集五:此次题目集共有五题,题量较多但是难度不一。第一题为找出最长单词,本题主要考察字符串的字符长度比较,同时还需要运用split将单词分隔开,题目较简单;第二题为合并两个有序数组为新的有序数组,本题主要考察数组的运用及数据的排序,题目较简单;第三题为对整形数据排序,本题主要考察插入排序、选择排序和冒泡排序的算法,题目较简单;第四题为统计java程序中关键词的出现次数,本题主要考察正则表达式的使用及接口的使用,对正则表达式及接口使用要求较高,题目较复杂;第五题为日期问题面向对象聚合二,和上次题目集的第二题考察内容大致一直,不过对日期类的设计与联系有了一定程度的改变,有了上次作业的经验,此次作业相对较简单。
题目集六:此次题目集共有六题,题量较多但是难度较小。第一题为正则表达式训练-QQ号校验,本题主要考察正则表达式的使用,题目相对较简单;第二题为字符串训练-字符排序,本题主要考察字符串与字符数组的转化,题目相对较简单;第三题为正则表达式训练-验证码校验,本题主要考察正则表达式的使用,题目相对较简单;第四题为正则表达式训练-学号校验,本题同样考察正则表达式,复杂程度较前两题有所提高,题目难度偏低;第五题为图形继承与多态,本体主要考察java中的继承与多态,还包括ArrayList的常用方法及和数组的关系的使用,难度和复杂度较大;第六题为实现图形接口及多态性,主要需要实现类的封装性、继承性和多态性,综合性较强,但复杂度一般。
设计与分析:
首先是对题目集4(7-2)与题目集5(7-4)两种日期类聚合设计的优劣比较
下面分别附上两题的类图
下面分别附上两题的源代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year = 0; int month = 0; int day = 0; int choice = input.nextInt(); if (choice == 1) { // test getNextNDays method int m = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } m = input.nextInt(); if (m < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print(date.getDay().getMonth().getYear().getValue() + "-" + date.getDay().getMonth().getValue() + "-" + date.getDay().getValue() + " next " + m + " days is:"); System.out.println(date.getNextNDays(m).showDate()); } else if (choice == 2) { // test getPreviousNDays method int n = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } n = input.nextInt(); if (n < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print(date.getDay().getMonth().getYear().getValue() + "-" + date.getDay().getMonth().getValue() + "-" + date.getDay().getValue() + " previous " + n + " days is:"); System.out.println(date.getPreviousNDays(n).showDate()); } else if (choice == 3) { // test getDaysofDates method year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); int anotherYear = Integer.parseInt(input.next()); int anotherMonth = Integer.parseInt(input.next()); int anotherDay = Integer.parseInt(input.next()); DateUtil fromDate = new DateUtil(year, month, day); DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:" + fromDate.getDaysofDates(toDate)); } else { System.out.println("Wrong Format"); System.exit(0); } } else { System.out.println("Wrong Format"); System.exit(0); } } } class DateUtil { Day day; public DateUtil(){ } public DateUtil(int d, int m, int y){ this.day = new Day(d,m,y); } public Day getDay() { return day; } public void setDay(Day d) { this.day = d; } public boolean checkInputValidity(){//检测输入的年、月、日是否合法 if(this.getDay().getMonth().getYear().validate()&&this.getDay().getMonth().validate()&&day.validate()) return true; return false; } public boolean compareDates(DateUtil date){//比较当前日期与date的大小(先后) if (date.getDay().getMonth().getYear().getValue()<this.getDay().getMonth().getYear().getValue()) return false; else if (date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue() &&date.getDay().getMonth().getValue()<this.getDay().getMonth().getValue()) return false; 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()) return false; return true; } public boolean equalTwoDates(DateUtil date){//判断两个日期是否相等 if (this.getDay().getValue()==date.getDay().getValue() && this.getDay().getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue() && this.getDay().getMonth().getValue()==date.getDay().getMonth().getValue()) return true; return false; } public String showDate(){//以“year-month-day”格式返回日期值 return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue(); } public DateUtil getNextNDays(int n){//取得year-month-day的下n天日期 int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; int year=0, month=0, day=0; int rest = restday(this); if (rest>n) {//本年 year=this.getDay().getMonth().getYear().getValue(); int mday = arr[this.getDay().getMonth().getValue()]; if (this.getDay().getMonth().getYear().isLeapYear()&&this.getDay().getMonth().getValue()==2) { mday++; } mday-=this.getDay().getValue();//本月剩余的日期 if (mday>=n) { //本月 month = this.getDay().getMonth().getValue(); day = n+this.getDay().getValue(); } else{ //其他月 n-=mday; month = this.getDay().getMonth().getValue()+1; int k = month; while(n-arr[k]>0&&k<=12){ n -= arr[k]; month++; k++; } day = n; } } else { n-=rest; year = this.getDay().getMonth().getYear().getValue()+1; int y = 365; if (new Year(year).isLeapYear()) { y++; } while(n-y>0){ n-=y; year++; y=365; if (new Year(year).isLeapYear()) y++; } int k = 1; while(n-arr[k]>0&&k<=12){ n -= arr[k]; k++; } month = k; day = n; } // System.out.println(this.showDate()+" next "+n+" days is:"+year+"-"+month+"-"+day); return new DateUtil(year, month, day); } public int restday(DateUtil d) { int n = 0; int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; for (int i = d.getDay().getMonth().getValue()+1; i <=12; i++) { n+=arr[i]; } n+=arr[d.getDay().getMonth().getValue()]-d.getDay().getValue(); if(d.getDay().getMonth().getYear().isLeapYear()&&d.getDay().getMonth().getValue()<=2) n++; return n; } public DateUtil getPreviousNDays(int n){//取得year-month-day的前n天日期 int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; int year=0, month=0, day=0; int rest = 365-restday(this); if (this.getDay().getMonth().getYear().isLeapYear()) { rest++; } if (rest>n) {//本年 year=this.getDay().getMonth().getYear().getValue(); int mday=this.getDay().getValue();//本月剩余的日期 if (mday>n) { //本月 month = this.getDay().getMonth().getValue(); day = mday-n; } else{ //其他月 n-=mday; month = this.getDay().getMonth().getValue()-1; if (month==0) { month = 12; year=this.getDay().getMonth().getYear().getValue()-1; } int k = month; while(n-arr[k]>0&&k>=0){ n -= arr[k]; month--; k--; } day = arr[k]-n; if (new Year(year).isLeapYear()&&month==2) { day++; } } } else { n-=rest; year = this.getDay().getMonth().getYear().getValue()-1; int y = 365; if (new Year(year).isLeapYear()) { y++; } while(n-y>0){ n-=y; year--; y=365; if (new Year(year).isLeapYear()) y++; } int k = 12; while(n-arr[k]>0&&k>=0){ n -= arr[k]; k--; } month = k; day = arr[k]-n; if (new Year(year).isLeapYear()&&month==2) { day++; } } // System.out.println(this.showDate()+" previous "+n+" days is:"+year+"-"+month+"-"+day); return new DateUtil(year, month, day); } public int getDaysofDates(DateUtil date){//求当前日期与date之间相差的天数 DateUtil pred = this; DateUtil nextd = date; if (this.equalTwoDates(date)) { return 0; } else if (!this.compareDates(date)) { pred = date; nextd = this; } int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; int i,j,d = 0; for(i=pred.getDay().getMonth().getYear().getValue()+1;i<nextd.getDay().getMonth().getYear().getValue();i++) { d=d+365; if(new Year(i).isLeapYear()) d++; } if (pred.getDay().getMonth().getYear().getValue()!=nextd.getDay().getMonth().getYear().getValue()) { for(j=pred.getDay().getMonth().getValue()+1;j<=12;j++) d=d+arr[j]; d+=arr[pred.getDay().getMonth().getValue()]-pred.getDay().getValue(); for(j=1;j<nextd.getDay().getMonth().getValue();j++) d+=arr[j]; d+=nextd.getDay().getValue(); if(pred.getDay().getMonth().getYear().isLeapYear()&&pred.getDay().getMonth().getValue()<=2) d++; if (nextd.getDay().getMonth().getYear().isLeapYear()&&nextd.getDay().getMonth().getValue()>2) { d++; } } else if(pred.getDay().getMonth().getYear().getValue()==nextd.getDay().getMonth().getYear().getValue()&&pred.getDay().getMonth().getValue()!=nextd.getDay().getMonth().getValue()){ for(j=pred.getDay().getMonth().getValue()+1;j<=nextd.getDay().getMonth().getValue()-1;j++) d+=arr[j]; d+=arr[pred.getDay().getMonth().getValue()]-pred.getDay().getValue(); d+=nextd.getDay().getValue(); if(pred.getDay().getMonth().getYear().isLeapYear()&&pred.getDay().getMonth().getValue()<=2) d++; } else if(pred.getDay().getMonth().getYear().getValue()==nextd.getDay().getMonth().getYear().getValue()&&pred.getDay().getMonth().getValue()==nextd.getDay().getMonth().getValue()){ d=nextd.getDay().getValue()-pred.getDay().getValue(); } return d; } } class Day{ int value; Month month; int mon_maxnum[]= {31,28,31,30,31,30,31,31,30,31,30,31}; public Day() { } public Day(int yearValue,int monthValue,int dayValue) { this.month = new Month(yearValue,monthValue); this.value = dayValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Month getMonth() { return month; } public void setMonth(Month value) { this.month = value; } public void resetMin() { value=1; } public void resetMax() { value=mon_maxnum[month.getValue()-1]; } public boolean validate() { if(this.getMonth().getYear().isLeapYear()) mon_maxnum[1]++; if(1<=value&&mon_maxnum[month.getValue()-1]>=value) return true; return false; } public void dayIncrement() { value++; } public void dayReduction() { value--; } } class Month{ int value; Year year; public Month() { } public Month(int yearValue,int monthValue) { this.year = new Year(yearValue); this.value = monthValue; } 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 void resetMin() { value=1; } public void resetMax() { value=12; } public boolean validate() { if(1<=value&&12>=value) return true; return false; } public void monthIncrement() { value++; } public void monthReduction() { value--; } } class Year{ int value; public Year() { } public Year(int value) { this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public boolean isLeapYear(){//判断year是否为闰年 boolean y1 = value%4 == 0; boolean y2 = value%100 != 0; boolean y3 = value%400 == 0; if((y1&&y2)||y3) return true; else return false; } public boolean validate() { if(value<=2020&&value>=1820) return true; return false; } public void yearIncrement() { value++; } public void yearReduction() { value--; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year = 0; int month = 0; int day = 0; int choice = input.nextInt(); if (choice == 1) { // test getNextNDays method int m = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } m = input.nextInt(); if (m < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); System.out.println(date.getNextNDays(m).showDate()); } else if (choice == 2) { // test getPreviousNDays method int n = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } n = input.nextInt(); if (n < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print( date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); System.out.println(date.getPreviousNDays(n).showDate()); } else if (choice == 3) { //test getDaysofDates method year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); int anotherYear = Integer.parseInt(input.next()); int anotherMonth = Integer.parseInt(input.next()); int anotherDay = Integer.parseInt(input.next()); DateUtil fromDate = new DateUtil(year, month, day); DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:" + fromDate.getDaysofDates(toDate)); } else { System.out.println("Wrong Format"); System.exit(0); } } else{ System.out.println("Wrong Format"); System.exit(0); } } } class DateUtil { private int year; private int month; private int day; public DateUtil(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public DateUtil(){} public void setYear(int year) { this.year = year; } public void setMonth(int month) { this.month = month; } public void setDay(int day) { this.day = day; } public int getYear() { return year; } public int getMonth() { return month; } public int getDay() { return day; } private final int[] DAY_OF_MONTH = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; private int getDayOfMonth(int year, int month) { int days = DAY_OF_MONTH[month - 1]; if (month == 2 && isLeapYear(year)) { days = 29; } return days; } public boolean checkInputValidity()//检测输入的年、月、日是否合法 { if (year < 1820 || year > 2020) return false; if (month < 1 || month > 12) return false; // int _day = this.getDayOfMonth(year, month); // return day <= _day; return day >= 1 && day <= 31; } public boolean isLeapYear(int year)//判断year是否为闰年 { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; } public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期 { int year = this.year; int month = this.month; int day = this.day; // day = Math.min(day, this.getDayOfMonth(year, month)); for (int i = 0; i < n; i++) { day++; if (day > getDayOfMonth(year, month)) { day = 1; month++; if (month > 12) { month = 1; year++; } } } return new DateUtil(year, month, day); } public DateUtil getPreviousNDays(int n)//取得year-month-day的前n天日期 { int year = this.year; int month = this.month; int day = this.day; for (int i = 0; i < n; i++) { day--; while (day < 1) { month--; if (month < 1) { month = 12; year--; } day += getDayOfMonth(year, month); } } return new DateUtil(year, month, day); } public boolean compareDates(DateUtil date)//比较当前日期与date的大小(先后) { if (this.year > date.year) return true; if (this.year == date.year) { if (this.month > date.month) return true; if (this.month == date.month) { if (this.day >= date.day) return true; } } return false; } public boolean equalTwoDates(DateUtil date)//判断两个日期是否相等 { if (date != null) { if (year == date.year && month == date.month && day == date.day) { return true; } } return false; } private static final int[] mon = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; public int getDaysofDates(DateUtil date)//求当前日期与date之间相差的天数 { DateUtil dateUtil1 = this; // 小 DateUtil dateUtil2 = date; // 大 if (this.compareDates(date)) { dateUtil1 = date; dateUtil2 = this; } int days; int leapYearNum = 0; for (int i = dateUtil1.getYear(); i < dateUtil2.getYear(); i++) { if (isLeapYear(i)) { leapYearNum++; } } days = 365 * (dateUtil2.getYear() - dateUtil1.getYear()) + leapYearNum; int d1 = mon[dateUtil1.getMonth() - 1] + dateUtil1.getDay() + (dateUtil1.getMonth() > 2 && isLeapYear(dateUtil1.getYear()) ? 1 : 0); int d2 = mon[dateUtil2.getMonth() - 1] + dateUtil2.getDay() + (dateUtil2.getMonth() > 2 && isLeapYear(dateUtil2.getYear()) ? 1 : 0); return days - d1 + d2; } public String showDate()//以“year-month-day”格式返回日期值 { return year + "-" + month + "-" + day; } }
日期聚合一与日期聚合二都主要考察的是类的封装,聚合一利用类之间的关系进行逐层封装,封装的更加严密但同时也大大增加了代码的复杂性,需要使用数据时需要逐层调用,大大加大了代码需要的内存,而聚合二是通过一个DateUtil类来与其他三个年、月、日类建立联系。如下图:
这样做的好处在于使用时只需直接调用某个类的get方法,而不需要繁琐的逐层调用数据,大大节省了内存空间及代码的繁琐程度。
接着对题目集4(7-3)进行分析,下面附上源代码:
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int id = in.nextInt(); switch (id){ case 1 :{ double r = in.nextDouble(); if (r <= 0){ System.out.println("Wrong Format"); System.exit(1);//输入错误,直接结束; } Circle circle = new Circle(); circle.setRadius(r); System.out.printf("Circle's area:%.2f\n", circle.getArea()); break; } case 2 :{ double length = in.nextDouble(); double width = in.nextDouble(); if (length <= 0 || width <= 0){ System.out.println("Wrong Format"); System.exit(1); } Rectangle rectangle = new Rectangle(); rectangle.setLength(length); rectangle.setWidth(width); System.out.printf("Rectangle's area:%.2f\n", rectangle.getArea()); break; } case 3 :{ double radius = in.nextDouble(); if (radius <= 0){ System.out.println("Wrong Format"); System.exit(1); } Ball ball = new Ball(); ball.setRadius(radius); System.out.printf("Ball's surface area:%.2f\n", ball.getArea()); System.out.printf("Ball's volume:%.2f\n", ball.getVolume()); break; } case 4 :{ double length = in.nextDouble(); double width = in.nextDouble(); double height = in.nextDouble(); if (length <= 0 || width <= 0 || height <= 0){ System.out.println("Wrong Format"); System.exit(1); } Box box = new Box(); box.setLength(length); box.setWidth(width); box.setHeight(height); System.out.printf("Box's surface area:%.2f\n", box.getArea()); System.out.printf("Box's volume:%.2f\n", box.getVolume()); break; } default :{ System.out.println("Wrong Format"); System.exit(1); } } } } class Shape{ public Shape(){ System.out.println("Constructing Shape"); } public double getArea(){ return 0.0; } } class Circle extends Shape{ private double radius; public Circle(){ System.out.println("Constructing Circle"); } public double getRadius(){ return radius; } public void setRadius(double radius){ this.radius = radius; } @Override public double getArea(){ return radius * radius * Math.PI; } } class Rectangle extends Shape{ private double width; private double length; public Rectangle(){ System.out.println("Constructing Rectangle"); } 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; } @Override public double getArea(){ return width * length; } } class Ball extends Circle{ public Ball(){ System.out.println("Constructing Ball"); } @Override public double getArea(){ return 4 * super.getRadius() * super.getRadius() * Math.PI; } public double getVolume(){ return 4.0 / 3.0 * Math.PI * Math.pow(super.getRadius(), 3); } } class Box extends Rectangle{ private double height; public Box(){ System.out.println("Constructing Box"); } public double getHeight(){ return height; } public void setHeight(double height){ this.height = height; } @Override public double getArea(){ return (super.getArea() + height * super.getWidth() + height * super.getLength()) * 2; } public double getVolume(){ return height * super.getArea(); } }
该题主要利用类的继承与方法的重写进行图形的继承,多方法的重写能够更加有效的进行面积的计算,并且对各个类的私有属性进行了一定的封装,类Circle,继承自Shape;类Rectangle,继承自Shape;类Ball,继承自Circle;类Box,继承自Rectangle;通过继承的使用使代码能够更加简便与高效。
题目集6(7-5、7-6)主要是利用类的封装性、继承性和多态性。
7-5中getArea()方法为抽象方法,功能为求得图形的面积;validate()方法也为抽象方法,对图形的属 性进行合法性校验;toString()继承自 Object,功能为输出图形的面积信息;此次作业采用的使抽象类定义、实体类构建的方式。。即 Shape 为抽象类,Circle、Rectangle 及 Triangle 为实体类。另外此题中还需要使用到ArrayList类,用于对list 中的图形对象在 list 中进行排序。
7-6中GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口;该题综合了类的继承、类的封装、方法的重写与接口的使用。下面附上该题类图与源代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); double r = in.nextDouble(); double l = in.nextDouble(); double w = in.nextDouble(); if(l<=0||w<=0||r<=0) { System.out.println("Wrong Format"); System.exit(0); } Circle circle = new Circle(r); Rectangle rectangle = new Rectangle(w,l); GetArea getArea = new GetArea(); System.out.println(String.format("%.2f",circle.getArea())); System.out.println(String.format("%.2f",rectangle.getArea())); } } class Circle { private double radius; public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public Circle() { } public Circle(double radius) { setRadius(radius); } public double getArea() { return Math.PI*getRadius()*getRadius(); } } class Rectangle { private double width; private double length; public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public Rectangle() { } public Rectangle(double width ,double length) { setLength(length); setWidth(width); } public double getArea() { return getLength()*getWidth(); } } class GetArea { Circle circle = new Circle(); Rectangle rectangle = new Rectangle(); public double getRArea() { return rectangle.getArea(); } public double getCArea() { return circle.getArea(); } }
该题在多处运用了类的封装,如:

这样能够大大提高代码的安全性。该题还以GetArea为接口,通过GetArea来联系Circle及Rectangle类中的求面积的方法,将所有类都联系起来,提高了代码的效率。
本次题目集中有三题都为正则表达式训练,分别为题目集六(7-1)、题目集六(7-3)、题目集六(7-4)。
题目集六(7-1)为QQ号检验,主要思路为利用正则表达式提取数字字符,若匹配失败,则输出错误,如下图:
题目集六(7-3)为验证码校验,主要思路为利用正则表达式提取非数字且非字母字符,若匹配成功,则输出错误,如下图:
题目集六(7-4)为学号校验,该题对正则表达式要求较精密,下面附上正则表达式代码:
regex = "[2][0][2][0][1][1-7][0-3][0-9]|[2][0][2][0][7][1-3][0-3][0-9]|[2][0][2][0][8][1-2][0-3][0-9]|[2][0][2][0][1][1-7][4][0]|[2][0][2][0][7][1-3][4][0]|[2][0][2][0][8][1-2][4][0]"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(num);t
通过对固定的格式进行校验,若匹配成功,则输出正确,反之则输出错误。
题目集五(7-4)为统计java程序中关键词出现的次数,该题要求使用List、Set或Map中一种或多种接口,主要通过正则表达式进行分割,分割后再进行匹配。对于Set、List和Map三种集合,最常用的实现类分别是HashSet、ArrayList和HashMap三个实现类。Map实现类用于保存具有映射关系的数据(key-value)。Set、List和Map可以看做集合的三大类。List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问。Set集合是无序集合,集合中的元素不可以重复,访问集合中的元素只能根据元素本身来访问。
采坑心得:
通过这三次的题目集训练,使我能够熟练掌握封装、继承与多态,并且对接口也有一定程度的学习,首先,我理解了只要是非静态类,在其他类中需要调用,都必须创建这个类的对象,印证了那第一堂课中的那句‘java一切皆类’;然后我知道了重写都是方法的重写,和属性无关,若将属性进行重写,程序会报错;而多态是方法的多态,属性没有多态。
改进建议:
希望在PTA实验测试时能够多提供些测试点,方便我们代码的测试及编写,另外测试点的名字希望能够清晰的指明问题所在。
总结:
1. 对属性和方法进行封装能够提高程序的安全性,保护数据,而且还能隐藏代码的细节,所以在代码的编写过程中要尽可能的对数据进行封装。
2. super关键字会调用父类的构造方法,所以必须在构造方法的第一个,且super不能和this同时调用构造方法。
3. 重写都是方法的重写,和属性无关;多态是方法的多态,属性没有多态。
4. 方法的重写需要有继承关系,是子类重写父类的方法(要求 :方法名必须相同、参数列表必须相同、修饰符范围可以缩小不能扩大)
5. 多态的存在条件:继承关系,方法需要重写,父类引用指向子类对象!