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. 多态的存在条件:继承关系,方法需要重写,父类引用指向子类对象!
浙公网安备 33010602011771号