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

 

posted @ 2021-04-29 09:10  不劝  阅读(83)  评论(0)    收藏  举报