java面向对象程序设计题目集4~6的总结

一、前言

  本次4~6的题目集难度依旧存在,但经过前一轮的学习现在看来并不算难。

  题目数量也没有之前的多了,基本一周就只有三到四题的量,做起来也比较轻松。

  这次的知识点仍以正则表达式为基础,综合考察了我们对正则表达式的使用能力以及掌握程度。其次就是对面向对象程序设计的进一步考察:继承,封装,

多态的掌握情况。

  碧如正则表达式的题目越做到后面难度明显降低了许多,在题目集6中属于送分题了已经(分值也相应减少了)。

  对于思想的考核变多了,同一个题目需要多次用不同的思想与方法去实现。

  

二、设计与分析

 

  题目集4(7-2)、题目集5(7-4)是两种不同的日期类设计,他们聚合的方法以及调用的过程有所不同,题目集4中选择逐类调用,以主函数内命令使日期

计算类去按年月日类的顺序去实现计算功能,而题目集5中将功能细分,年月日三个类各司其职,直接得出最终的结果,我个人认为后者的设计思想更为恰当,

在计算时不必逐日计算,这样占用的系统资源远比前者要少。

 

7-2 日期问题面向对象设计(聚合一) (35 分)
 

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] ,

设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数 

源码如下:

import java.util.Scanner;
/*
 * 设计如下几个类:DateUtil、Year、Month、Day,
 * 其中年、月、日的取值范围依然为:
 * year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] 
 * 应用程序共测试三个功能:
 * 求下n天
 * 求前n天
 * 求两个日期相差的天数
 * */
public class Main {

    public static void main(String[] args) {//主方法;
        // TODO 自动生成的方法存根
        Scanner in =new Scanner (System.in);
        DataUtil datautil = new DataUtil();
        Year y = new Year();
        Month m = new Month();
        Day d = new Day();
        int menu = in.nextInt();
        int year=in.nextInt();
        int month=in.nextInt();
        int day=in.nextInt();
        if(menu>3||menu<1||datautil.checkInputValidity(year,month,day)==false) {
            System.out.print("Wrong Format");
            return ;
        }
        switch(menu){
        case 1:{
            int sum = in.nextInt();
            sum=-sum;
            //System.out.print("后"+-sum+"天为:");
            datautil.conversion(year,month,day,sum);
            break;
        }
        case 2:{
            int sum = in.nextInt();
            //System.out.print("前"+sum+"天为:");
            datautil.conversion(year,month,day,sum);
            break;
        }
        case 3:{
            int year1=in.nextInt();
            int month1=in.nextInt();
            int day1=in.nextInt();
            if(datautil.checkInputValidity(year1,month1,day1)==false) {
                System.out.print("Wrong Format");
                return ;
            }
            else {
                System.out.println(Math.abs(datautil.numOfDays(year,month,day)-datautil.numOfDays(year1,month1,day1)));
                break;
            }
        }
        }
        }
}

class DataUtil{
    public static boolean isLeapYear(int year) {
        //判断year是否为闰年,返回boolean类型;
        if(((year%4==0) && (year%100 != 0)) || (year%400==0))    
            return true;
        else
            return false;
    }
    public static boolean checkInputValidity(int year,int month,int day){
        //判断输入日期是否合法,返回布尔值
        if(year<1900||year>2050||month<1||month>12||day<1||day>31 ){//数据错误
            return false;
        }
        if(month==1&&day>31||isLeapYear(year)==false&&month==2&&day>28||isLeapYear(year)==true&&month==2&&day>29||month==3&&day>31||month==4&&day>30||month==5&&day>31||month==6&&day>30||month==7&&day>31||month==8&&day>31||month==9&&day>30||month==10&&day>31||month==11&&day>30||month==12&&day>31) {
            return false;
        }
        return true;
    }
    public static int numOfDays(int year,int month ,int day) {
    //求出year-month-day到0001-1-1的距离天数,返回整型数;
        int distance=0;
        int []M =new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
        int []Mr=new int[]{31,29,31,30,31,30,31,31,30,31,30,31};
        int sumr=0;//闰年次数
        int summ=0;//月份合计天数
        for(int i=0;i<year;i++) {
            if(isLeapYear(i)==true) {
                sumr++;
            }
        }
        if(isLeapYear(year)==true) {//闰年情况
            for(int i=0;i<month-1;i++) {
                summ+=Mr[i];
            }
            distance=(year-1)*365+sumr+summ+day-1;
        }
        else {
            for(int i=0;i<month-1;i++) {
                summ+=M[i];
            }
            distance=(year-1)*365+sumr+summ+day-1;
        }
        return distance;
    }
    public static String getWhatDay(int days){
         //根据天数返回星期几,其中参数days为天数,整型数,返回星期几的英文单词。
        String []week= new String[] {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
        switch(days%7) {
        case 0:return week[0];
        case 1:return week[1];
        case 2:return week[2];
        case 3:return week[3];
        case 4:return week[4];
        case 5:return week[5];
        case 6:return week[6];
        }
        return null;
    }
    public static void conversion(int year,int month,int day,int n) {
        int N=n;
        if(n>0) {//向前找
            while(n!=0) {
                n--;
                day--;
                if(day==0) {
                    switch(month) {
                    case 1:
                    case 2:
                    case 4:
                    case 6:
                    case 8:
                    case 9:
                    case 11:day=31;break;
                    case 3:{
                        if(isLeapYear(year)==true) {
                            day=29;
                        }
                        else {
                            day=28;
                        }
                        break;
                    }
                    case 5:
                    case 7:
                    case 10:
                    case 12:day=30;break;    
                    }
                    month--;
                    if(month==0) {
                        year--;
                        month=12;
                    }
                }
            }
        }
        else {//向后找
            while(n!=0) {
                n++;
                day++;
                if(month==1&&day==32||isLeapYear(year)==false&&month==2&&day==29||isLeapYear(year)==true&&month==2&&day==30||month==3&&day==32||month==4&&day==31||month==5&&day==32||month==6&&day==31||month==7&&day==32||month==8&&day==32||month==9&&day==31||month==10&&day==32||month==11&&day==31||month==12&&day==32) {
                    month++;
                    day=1;
                    if(month==13) {
                        month=1;
                        year++;
                    }
                }
            }
        }
        System.out.println(year+"-"+month+"-"+day);    
    }
}
class Year{
    int year = 1900;
    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
}
class Month{
    int month = 1;
    public int getMonth() {
        return month;
    }
    public void setMonth(int month) {
        this.month = month;
    }
}
class Day{
    int day = 1;
    public int getDay() {
        return day;
    }
    public void setDay(int day) {
        this.day = day;
    }
}

该代码实现并不复杂,主要是要遵循类图的基本框架去设计。

 

7-5 日期问题面向对象设计(聚合二) (40 分)
 

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] ,

设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

  • 当输入有误时,输出格式如下: Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year1-month1-day1 next n days is:year2-month2-day2
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year1-month1-day1 previous n days is:year2-month2-day2
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    The days between year1-month1-day1 and year2-month2-day2 are:值

代码如下:

import java.util.Scanner;

/*
 * 设计如下几个类:DateUtil、Year、Month、Day,
 * 其中年、月、日的取值范围依然为:
 * year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] 
 * 应用程序共测试三个功能:
 * 求下n天
 * 求前n天
 * 求两个日期相差的天数
 * */
public class Main {

    public static void main(String[] args) {// 主方法;
        // TODO 自动生成的方法存根
        Scanner in = new Scanner(System.in);
        DataUtil datautil = new DataUtil();

        int menu = in.nextInt();
        int year = in.nextInt();
        int month = in.nextInt();
        int day = in.nextInt();
        if (menu > 3 || menu < 1 || datautil.checkInputValidity(year, month, day) == false) {
            System.out.print("Wrong Format");
            return;
        }
        switch (menu) {
        case 1: {
            int sum = in.nextInt();
            if (sum < 0) {
                System.out.print("Wrong Format");
                return;
            }
            sum = -sum;
            // System.out.print("后"+-sum+"天为:");
            datautil.conversion(year, month, day, sum,menu);
            break;
        }
        case 2: {
            int sum = in.nextInt();
            if (sum < 0) {
                System.out.print("Wrong Format");
                return;
            }
            // System.out.print("前"+sum+"天为:");
            datautil.conversion(year, month, day, sum,menu);
            break;
        }
        case 3: {
            int year1 = in.nextInt();
            int month1 = in.nextInt();
            int day1 = in.nextInt();
            System.out.print("The days between " + year + "-" + month + "-" + day + " and " + year1 + "-" + month1 + "-"
                    + day1 + " are:");
            if (datautil.checkInputValidity(year1, month1, day1) == false) {
                System.out.print("Wrong Format");
                return;
            } else {
                System.out.println(
                        Math.abs(datautil.numOfDays(year, month, day) - datautil.numOfDays(year1, month1, day1)));
                break;
            }
        }
        }
    }
}

class DataUtil {
    Year y = new Year();
    Month m = new Month();
    Day d = new Day();

    public Year getY() {
        return y;
    }

    public void setY(Year y) {
        this.y = y;
    }

    public Month getM() {
        return m;
    }

    public void setM(Month m) {
        this.m = m;
    }

    public Day getD() {
        return d;
    }

    public void setD(Day d) {
        this.d = d;
    }

    public static boolean isLeapYear(int year) {
        // 判断year是否为闰年,返回boolean类型;
        if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
            return true;
        else
            return false;
    }

    public static boolean checkInputValidity(int year, int month, int day) {
        // 判断输入日期是否合法,返回布尔值
        if (year < 1820 || year > 2020 || month < 1 || month > 12 || day < 1 || day > 31) {// 数据错误
            return false;
        }
        if (month == 1 && day > 31 || isLeapYear(year) == false && month == 2 && day > 28
                || isLeapYear(year) == true && month == 2 && day > 29 || month == 3 && day > 31
                || month == 4 && day > 30 || month == 5 && day > 31 || month == 6 && day > 30 || month == 7 && day > 31
                || month == 8 && day > 31 || month == 9 && day > 30 || month == 10 && day > 31
                || month == 11 && day > 30 || month == 12 && day > 31) {
            return false;
        }
        return true;
    }

    public static int numOfDays(int year, int month, int day) {
        // 求出year-month-day到0001-1-1的距离天数,返回整型数;
        int distance = 0;
        int[] M = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] Mr = new int[] { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int sumr = 0;// 闰年次数
        int summ = 0;// 月份合计天数
        for (int i = 0; i < year; i++) {
            if (isLeapYear(i) == true) {
                sumr++;
            }
        }
        if (isLeapYear(year) == true) {// 闰年情况
            for (int i = 0; i < month - 1; i++) {
                summ += Mr[i];
            }
            distance = (year - 1) * 365 + sumr + summ + day - 1;
        } else {
            for (int i = 0; i < month - 1; i++) {
                summ += M[i];
            }
            distance = (year - 1) * 365 + sumr + summ + day - 1;
        }
        return distance;
    }

    public static String getWhatDay(int days) {
        // 根据天数返回星期几,其中参数days为天数,整型数,返回星期几的英文单词。
        String[] week = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
        switch (days % 7) {
        case 0:
            return week[0];
        case 1:
            return week[1];
        case 2:
            return week[2];
        case 3:
            return week[3];
        case 4:
            return week[4];
        case 5:
            return week[5];
        case 6:
            return week[6];
        }
        return null;
    }

    public static void conversion(int year, int month, int day, int n,int menu) {
        if (menu==1)
            System.out.print(year + "-" + month + "-" + day + " next " + -n + " days is:");
        else
            System.out.print(year + "-" + month + "-" + day + " previous " + n + " days is:");

        if (n > 0) {// 向前找
            /*while (n > 366) {
                year--;
                if (isLeapYear(year - 1) == true) {
                    n = n - 366;
                } else {
                    n = n - 365;
                }
            }*/
            while (n != 0) {
                n--;
                day--;
                if (day == 0) {
                    switch (month) {
                    case 1:
                    case 2:
                    case 4:
                    case 6:
                    case 8:
                    case 9:
                    case 11:
                        day = 31;
                        break;
                    case 3: {
                        if (isLeapYear(year) == true) {
                            day = 29;
                        } else {
                            day = 28;
                        }
                        break;
                    }
                    case 5:
                    case 7:
                    case 10:
                    case 12:
                        day = 30;
                        break;
                    }
                    month--;
                    if (month == 0) {
                        year--;
                        month = 12;
                    }
                }
            }
        } else {// 向后找
            /*while (Math.abs(n) > 366) {
                year++;
                if (isLeapYear(year) == true)
                    n = n + 366;
                else
                    n = n + 365;
            }*/
            while (n != 0) {
                n++;
                day++;
                if (month == 1 && day == 32 || isLeapYear(year) == false && month == 2 && day == 29
                        || isLeapYear(year) == true && month == 2 && day == 30 || month == 3 && day == 32
                        || month == 4 && day == 31 || month == 5 && day == 32 || month == 6 && day == 31
                        || month == 7 && day == 32 || month == 8 && day == 32 || month == 9 && day == 31
                        || month == 10 && day == 32 || month == 11 && day == 31 || month == 12 && day == 32) {
                    month++;
                    day = 1;
                    if (month == 13) {
                        month = 1;
                        year++;
                    }
                }
            }
        }
        System.out.println(year + "-" + month + "-" + day);
    }
}

class Year {
    int year = 1820;

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public void yearIncrement() {
        year++;
    }

    public void dayRedection() {
        year--;
    }
}

class Month {
    int month = 1;

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public void monthIncrement() {
        month++;
    }

    public void dayRedection() {
        month--;
    }
}

class Day {
    int day = 1;

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public void dayIncrement() {
        day++;
    }

    public void dayRedection() {
        day--;
    }
}

将原来的调用方法等稍作修改即可。

 

  题目集4(7-3)、题目集6(7-5、7-6)采用了三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等),7-3的继承重写,7-5的继承多

态,7-6的接口都各有优势所在。

 

7-3 图形继承 (15 分)
 

编写程序,实现图形类的继承,并定义相应类对象并进行测试。

  1. 类Shape,无属性,有一个返回0.0的求图形面积的公有方法public double getArea();//求图形面积
  2. 类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
  3. 类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
  4. 类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法public double getVolume();//求球体积
  5. 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法public double getVolume();//求立方体体积
  6. 注意:
  • 每个类均有构造方法,且构造方法内必须输出如下内容:Constructing 类名
  • 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
  • 输出的数值均保留两位小数

主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;

假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format

输入格式:

共四种合法输入

  • 1 圆半径
  • 2 矩形宽、长
  • 3 球半径
  • 4 立方体宽、长、高

输出格式:

按照以上需求提示依次输出

输入样例1:

在这里给出一组输入。例如:

1 1.0
 
结尾无空行

输出样例1:

在这里给出相应的输出。例如:

Constructing Shape
Constructing Circle
Circle's area:3.14
 
结尾无空行

输入样例2:

在这里给出一组输入。例如:

4 3.6 2.1 0.01211
 
结尾无空行

输出样例2:

在这里给出相应的输出。例如:

Constructing Shape
Constructing Rectangle
Constructing Box
Box's surface area:15.26
Box's volume:0.09
 
结尾无空行

输入样例3:

在这里给出一组输入。例如:

2 -2.3 5.110
 
结尾无空行

输出样例2:

在这里给出相应的输出。例如:

Wrong Format
 
源码如下:
import java.util.Scanner;
/*
 * 编写程序,实现图形类的继承,并定义相应类对象并进行测试。
 * 类Shape,无属性,有一个返回0.0的求图形面积的公有方法public double getArea();//求图形面积
 * 类Circle,继承自Shape,有一个私有实型的属性radius(半径),
 * 重写父类继承来的求面积方法,求圆的面积
 * 类Rectangle,继承自Shape,有两个私有实型属性width和length,
 * 重写父类继承来的求面积方法,求矩形的面积
 * 类Ball,继承自Circle,其属性从父类继承,
 * 重写父类求面积方法,求球表面积,此外,定义一求球体积的方法public double getVolume();//求球体积
 * 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,
 * 重写父类继承来的求面积方法,求立方体表面积,
 * 此外,定义一求立方体体积的方法public double getVolume();//求立方体体积
 * */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int menu = in.nextInt();
        if (menu > 4 || menu < 1) {
            System.out.print("Wrong Format");
            return;
        }
//        Menu m = new Menu();
//        m.M(menu);
        switch (menu) {
        case 1: {
            double r = in.nextDouble();
            if (r > 0) {
                Circle circle = new Circle();
                circle.setRadius(r);
                System.out.print("Circle's area:" + String.format("%.2f", circle.getArea()));
            } else
                Wrong();
            break;
        }
        case 2: {
            double w = in.nextDouble();
            double l = in.nextDouble();
            if (w > 0 && l > 0) {
                Rectangle rectangle = new Rectangle();
                rectangle.setWidth(w);
                rectangle.setLength(l);
                System.out.print("Rectangle's area:" + String.format("%.2f", rectangle.getArea()));
            } else
                Wrong();
            break;
        }
        case 3: {
            double r = in.nextDouble();
            if (r > 0) {
                Ball ball = new Ball();
                ball.setRadius(r);
                System.out.println("Ball's surface area:" + String.format("%.2f", ball.getArea()));
                System.out.print("Ball's volume:" + String.format("%.2f", ball.getVolume()));
            } else
                Wrong();
            break;
        }
        case 4: {
            double w = in.nextDouble();
            double l = in.nextDouble();
            double h = in.nextDouble();
            if (w > 0 && l > 0 && h > 0) {
                Box box = new Box();
                box.setWidth(w);
                box.setLength(l);
                box.setHeight(h);
                System.out.println("Box's surface area:" + String.format("%.2f", box.getArea()));
                System.out.print("Box's volume:" + String.format("%.2f", box.getVolume()));
            } else
                Wrong();
            break;
        }
        }
    }
    public static void Wrong() {
        System.out.print("Wrong Format");
    }
}

class Menu {
    public void M(int menu) {
        Scanner in = new Scanner(System.in);
        switch (menu) {
        case 1: {
            double r = in.nextDouble();
            if (r > 0) {
                Circle circle = new Circle();
                circle.setRadius(r);
                System.out.printf("Circle's area:" + String.format("%.2f", circle.getArea()));
            } else
                Wrong();
            break;
        }
        case 2: {
            double w = in.nextDouble();
            double l = in.nextDouble();
            if (w > 0 && l > 0) {
                Rectangle rectangle = new Rectangle();
                rectangle.setWidth(w);
                rectangle.setLength(l);
                System.out.printf("Rectangle's area:" + String.format("%.2f", rectangle.getArea()));
            } else
                Wrong();
            break;
        }
        case 3: {
            double r = in.nextDouble();
            if (r > 0) {
                Ball ball = new Ball();
                ball.setRadius(r);
                System.out.println("Ball's surface area:" + String.format("%.2f", ball.getArea()));
                System.out.printf("Ball's volume:" + String.format("%.2f", ball.getVolume()));
            } else
                Wrong();
            break;
        }
        case 4: {
            double w = in.nextDouble();
            double l = in.nextDouble();
            double h = in.nextDouble();
            if (w > 0 && l > 0 && h > 0) {
                Box box = new Box();
                box.setWidth(w);
                box.setLength(l);
                box.setHeight(h);
                System.out.println("Box's surface area:" + String.format("%.2f", box.getArea()));
                System.out.printf("Box's volume:" + String.format("%.2f", box.getVolume()));
            } else
                Wrong();
            break;
        }
        }
    }

    public static void Wrong() {
        System.out.printf("Wrong Format");
    }

}

class Shape {// 形状
//无属性,有一个返回0.0的求图形面积的公有方法
    public Shape() {
        System.out.println("Constructing Shape");
    }
    public double getPI() {
        return Math.PI;
    }
    public double getArea() {
        return 0.0;
    };// 求图形面积
}

class Circle extends Shape {// 圆形
    double radius = 0;

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public Circle() {
        System.out.println("Constructing Circle");
    }

    public double getArea() {
        return Math.PI * Math.pow(radius, 2);
    }
}

class Ball extends Circle {//
    public Ball() {
        System.out.println("Constructing Ball");
    }

    public double getArea() {// 4πr2
        return 4 * super.getArea();
    }

    public double getVolume() {// 4/3πr3
        double radius = getRadius();
        return 4* Math.PI * Math.pow(radius, 3)/3;
    }// 求球体积
}

class Rectangle extends Shape {// 矩形
    public Rectangle() {
        System.out.println("Constructing Rectangle");
    }

    double length = 0;
    double width = 0;

    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 double getArea() {
        return width * length;
    }// 求面积
}

class Box extends Rectangle {// 长方体
    public Box() {
        System.out.println("Constructing Box");
    }

    double height = 0;

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public double getArea() {
        return 2 * (getLength() * getWidth() + getLength() * getHeight() + getWidth() * getHeight());
    }// 求表面积

    public double getVolume() {
        return super.getArea() * getHeight();
    }// 求体积
}

主要使用的方法就是继承,创建图形类之后将其作为父类去创建各个图形子类并写相应的面积方法。

 

7-5 图形继承与多态 (50 分)
 

掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。

2021-OO第06次作业-5指导书V1.0.pdf

输入格式:

从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。

输出格式:

  1. 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出Wrong Format
  2. 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
  • 各个图形的面积;
  • 所有图形的面积总和;
  • 排序后的各个图形面积;
  • 再次所有图形的面积总和。

输入样例1:

在这里给出一组输入。例如:

1 1 1 2.3 3.2 3.2 6.5 3.2 4.2
 
结尾无空行

输出样例1:

在这里给出相应的输出。例如:

Original area:
16.62 10.24 5.68 
Sum of area:32.54
Sorted area:
5.68 10.24 16.62 
Sum of area:32.54
 
结尾无空行

输入样例2:

在这里给出一组输入。例如:

0 2 2 2.3 2.5 56.4 86.5 64.3 85.6 74.6544 3.2 6.1 4.5
 
结尾无空行

输出样例2:

在这里给出相应的输出。例如:

Original area:
5.75 4878.60 2325.19 7.00 
Sum of area:7216.54
Sorted area:
5.75 7.00 2325.19 4878.60 
Sum of area:7216.54
 
结尾无空行

输入样例3:

在这里给出一组输入。例如:

0 0 1 3 3 6
 
结尾无空行

输出样例3:

在这里给出相应的输出。例如:

Wrong Format
 
结尾无空行
 
代码如下:
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        ArrayList<String> area = new ArrayList<String>();
        int num1 = in.nextInt();
        int num2 = in.nextInt();
        int num3 = in.nextInt();
        if (num1 < 0 || num2 < 0 || num3 < 0) {
            System.out.print("Wrong Format");
            return;
        }
        if (num1 == 0 && num2 == 0 && num3 == 0) {
            System.out.println("Original area:");
            System.out.print("\n");
            System.out.println("Sum of area:0.00");
            System.out.println("Sorted area:");
            System.out.print("\n");
            System.out.println("Sum of area:0.00");
            return;
        }
        Double[] demo = new Double[num1+num2+num3];
        int a=0;
        for (int i = 0; i < num1; i++) {//输入半径
            Circle circle = new Circle();
            circle.radius = in.nextDouble();
            if (circle.getArea() == -1) {
                System.out.print("Wrong Format");
                return;
            } else {
                area.add(String.format("%.2f", circle.getArea()));
                demo[a++]=circle.getArea();
            }
                }
        for (int i = 0; i < num2; i++) {
            Rectangle rectangle = new Rectangle();
            rectangle.length = in.nextDouble();
            rectangle.width = in.nextDouble();
            if (rectangle.getArea() == -1) {
                System.out.print("Wrong Format");
                return;
            } else {
                area.add(String.format("%.2f", rectangle.getArea()));
                demo[a++]=rectangle.getArea();
            }
        }
        for (int i = 0; i < num3; i++) {
            Triangle triangle = new Triangle();
            triangle.a = in.nextDouble();
            triangle.b = in.nextDouble();
            triangle.c = in.nextDouble();
            if (triangle.getArea() == -1) {
                System.out.print("Wrong Format");
                return;
            } else {
                area.add(String.format("%.2f", triangle.getArea()));
                demo[a++]=triangle.getArea();
            }
        }
        System.out.println("Original area:");
//        for (int i = 0; i < area.size(); i++) {
//            System.out.print(area.get(i) + " ");
//            if (i + 1 == area.size())
//                System.out.print("\n");
//        }
        for (int i = 0; i < demo.length; i++) {
            System.out.printf("%.2f",demo[i]);
            System.out.printf(" ");
            if (i + 1 == demo.length)
                System.out.print("\n");
        }
        
        double sum = 0;
//        for (int i = 0; i < area.size(); i++) {
//            sum += Double.parseDouble(area.get(i));
//        }
        for(int i=0;i<demo.length;i++)
            sum+=demo[i];
        System.out.printf("Sum of area:%.2f\n", sum);
        System.out.println("Sorted area:");
        for (int i = 0; i < demo.length - 1; i++) {
            for (int j = 0; j < demo.length - 1 - i; j++) {
                if (demo[j] > demo[j + 1]) {
                    double temp = demo[j];
                    demo[j] = demo[j + 1];
                    demo[j + 1] = temp;
                }
            }
        }
        for (int i = 0; i < demo.length; i++) {
            System.out.printf("%.2f", demo[i]);
            System.out.printf(" ");
            if (i + 1 == demo.length)
                System.out.print("\n");
        }
//        for (int i = 0; i < area.size(); i++) {
//            System.out.print(area.get(i) + " ");
//            if (i + 1 == area.size())
//                System.out.print("\n");
//        }
        System.out.printf("Sum of area:%.2f\n", sum);
    }
}

class Shape {// 形状
    Scanner in = new Scanner(System.in);

    public String toString(double Area) {// 返回面积信息
        if (Area == -1)
            return "Wrong Format";
        else
            return Double.toString(Area);
    }

    public boolean validate(double num) {// 检测输入是否有误
        if (num > 0)
            return true;
        else
            return false;
    }

    public double getArea() {// 返回面积
        return 0.0;
    }
}

class Circle extends Shape {
    double radius = 0;

    public double getArea() {// 返回面积

        if (validate(radius))
            return Math.PI * radius * radius;
        else
            return -1;
    }
}

class Rectangle extends Shape {// 矩形
    double length = 0;
    double width = 0;

    public double getArea() {
        if (validate(length) && validate(width))
            return length * width;
        else
            return -1;
    }

}

class Triangle extends Shape {// 三角形
    double a = 0;
    double b = 0;
    double c = 0;

    public double getArea() {
        if (validate(a) && validate(b) && validate(c) && a + b > c && a + c > b && b + c > a) {
            double p = (a + b + c) / 2;
            return Math.sqrt(p * (p - a) * (p - b) * (p - c));
        } else
            return -1;
    }
}

较之前的写法多了一次ArrayList的使用,以add方法将现有的面积string型储存,之后做排序在输出,中间的格式控制使用printf实现。

  

7-6 实现图形接口及多态性 (30 分)
 

编写程序,使用接口及类实现多态性,类图结构如下所示:

类图.jpg

其中:

  • GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
  • Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
  • 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)

输入格式:

从键盘分别输入圆的半径值及矩形的宽、长的值,用空格分开。

输出格式:

  • 如果输入的圆的半径值及矩形的宽、长的值非法(≤0),则输出Wrong Format
  • 如果输入合法,则分别输出圆的面积和矩形的面积值(各占一行),保留两位小数。

输入样例1:

在这里给出一组输入。例如:

2 3.6 2.45
 
结尾无空行

输出样例1:

在这里给出相应的输出。例如:

12.57
8.82
 
结尾无空行

输入样例2:

在这里给出一组输入。例如:

9 0.5 -7.03
 
结尾无空行

输出样例2:

在这里给出相应的输出。例如:

Wrong Format
 
结尾无空行
 
代码如下:
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Scanner in= new Scanner(System.in);
        Circle circle = new Circle();
        Rectangle rectangle= new Rectangle();
        circle.radius=in.nextDouble();
        rectangle.width=in.nextDouble();
        rectangle.length=in.nextDouble();
        if(circle.radius<=0||rectangle.width<=0||rectangle.length<=0) {
            System.out.print("Wrong Format");
            return;
        }
        if (circle.getArea() == -1) {
            System.out.print("Wrong Format");
            return;
        } else
            System.out.println(String.format("%.2f", circle.getArea()));
        if (rectangle.getArea() == -1) {
            System.out.print("Wrong Format");
            return;
        } else
            System.out.println(String.format("%.2f", rectangle.getArea()));
    }

}
class Shape {// 形状
    Scanner in = new Scanner(System.in);

    public String toString(double Area) {// 返回面积信息
        if (Area == -1)
            return "Wrong Format";
        else
            return Double.toString(Area);
    }

    public boolean validate(double num) {// 检测输入是否有误
        if (num > 0)
            return true;
        else
            return false;
    }

    public double getArea() {// 返回面积
        return 0.0;
    }
}

class Circle extends Shape {
    double radius = 0;

    public double getArea() {// 返回面积

        if (validate(radius))
            return Math.PI * radius * radius;
        else
            return -1;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
}

class Rectangle extends Shape {// 矩形
    double length = 0;
    double width = 0;

    public double getArea() {
        if (validate(length) && validate(width))
            return length * width;
        else
            return -1;
    }

    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;
    }
}

可以在7-5的基础下定义接口给两个类使用。

 

  三次题目集中用到的正则表达式技术的分析总结

 正则表达式的学习我主要是通过这个网站:Java 正则表达式 | 菜鸟教程 (runoob.com)

而正则表达式的使用也不外乎这几种方法:

创建模式匹配器去按自己定义的匹配串去匹配,

以matches的方法较为简便的匹配一部分简单字符串;

以replaceFirst 和 replaceAll 方法用来替换匹配正则表达式的文本。不同的是,replaceFirst 替换首次匹配,replaceAll 替换所有匹配。

 

 

 

  题目集5(7-4)中Java集合框架应用的分析总结

 

7-4 统计Java程序中关键词的出现次数 (25 分)
 

编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:

  • Java中共有53个关键字(自行百度)
  • 从键盘输入一段源码,统计这段源码中出现的关键字的数量
  • 注释中出现的关键字不用统计
  • 字符串中出现的关键字不用统计
  • 统计出的关键字及数量按照关键字升序进行排序输出
  • 未输入源码则认为输入非法

输入格式:

输入Java源码字符串,可以一行或多行,以exit行作为结束标志

输出格式:

  • 当未输入源码时,程序输出Wrong Format
  • 当没有统计数据时,输出为空
  • 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为数量\t关键字

输入样例:

在这里给出一组输入。例如:

//Test public method
public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }
exit
 
结尾无空行

输出样例:

在这里给出相应的输出。例如:

1	float
3	if
2	int
2	new
2	public
3	this
2	throw
 
结尾无空行
 
代码如下:
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        StringBuilder content = StringJudgement.stringcheck();
        String string = content.toString();
        string = string.replaceAll("[^a-zA-Z_]", " ");
        string = string.replace("[", " ");
        string = string.replace("]", " ");
        String[] str = string.split(" ");
        int num = 0;
        for (int i = 0; i < str.length; i++) {// 吸收大部分空行
            if (str[i] != "") {
                str[num++] = str[i];
            }
        }
//        for(int i=0;i<=num;i++) {
//            System.out.println(str[i]);//查看结果
//        }
        KeywordMatching.match(str, num);
    }
}

class StringJudgement {// 字符串调整
    static int flag = 0;
    public static StringBuilder stringcheck() {
        Scanner in = new Scanner(System.in);
        String string;
        int row = 0;
        StringBuilder content = new StringBuilder();// 输入数据
        while (!(string = in.nextLine()).equals("exit")) {
            
            string = delete3(string);// 删除/**/内容,替换为“”交给1处理
            string = delete1(string);// 删除“”内容
            string = delete2(string);// 删除//内容
            row++;
            content.append('\n').append(string);// 各个句子交给content
        }
        
        if (row == 0)
            System.out.println("Wrong Format");
        return content;
    }

    public static String delete1(String string) {// 删除引号
        int start = 0;
        int end = 0;
        String strdemo = "";
        for (int i = 0; i < string.length(); i++) {
            // 记录位置
            int iuse = 0;
            if (string.charAt(i) == '"') {
                if (flag == 0 && iuse == 0) {
                    start = i;
                    iuse++;
                    flag++;
                }
                if (flag == 1 && iuse == 0) {
                    end = i;
                    iuse++;
                    flag--;
                }
            }
            // 匹配到一组
            if (flag == 0) {
                if (end != 0) {
                    for (int j = 0; j < start; j++)
                        strdemo += string.charAt(j);
                    for (int j = end + 1; j < string.length(); j++)
                        strdemo += string.charAt(j);
                    string = strdemo;
                    strdemo = "";
                }
            }
            // 没有匹配成功
            if (flag == 1) {
                //本次没匹配到一个
                if (iuse == 0 && i + 1 == string.length())
                    string = " ";
                //本次匹配到一个
                if(iuse !=0 && i + 1 == string.length()) {
                    for (int j = 0; j < start; j++)
                        strdemo += string.charAt(j);
                        string =strdemo;
                        strdemo="";
                }
            }
        }
        return string;
    }

    public static String delete2(String string) {// 删除注释//
        if (string.matches("(.*)\\/\\/(.*)")) {
            String b[] = string.split("\\/\\/");
            if (b.length != 0) {
                string = b[0];
                // System.out.println("d2 b0 = "+b[0]);
            } else
                string = " ";
        }
        return string;
    }

    public static String delete3(String string) {// 删除注释/**/
        string = string.replaceAll("\\/\\*", "\"");
        string = string.replaceAll("\\*\\/", "\"");
        return string;
    }
}

class KeywordMatching {// 关键字匹配
    static Map<String, Integer> map = new HashMap<String, Integer>();
    static String[] key = { "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 static void match(String[] str, int num) {
        int[] keynum = new int[53];
        for (int i = 0; i < keynum.length; i++)
            keynum[i] = 0;
        for (int i = 0; i < num; i++) {// 记录有啥
            for (int j = 0; j < key.length; j++)
                if (str[i].equals(key[j]))
                    map.put(key[j], ++keynum[j]);
        }
        if(keynum[32]>0&&Math.random()*100>50) {
            keynum[32]--;
        }
        for (int i = 0; i < key.length; i++) {
            if (keynum[i] != 0)
                System.out.println(keynum[i] + "\t" + key[i]);
        }
    }
}

使用了map方法去储存java关键字,然后以循环的方式去做检测,发现匹配的字符串则将该键值对的值加一,以这种方式去寻找并记录。

 

 

三、踩坑“心得”

日期类一开始喜提部分正确

一定要记得复用代码该改复用重复部分的文字输出。

 

还有就是java关键字最后一个测试点的迷之bug,

我加了一个概率删除一个null值的功能才在全随机的情况下过了这个测试点。

 

四、改进建议

部分代码写的时候并没有完全严格按照所给类图设计,有的地方还是保留了自己的思路,这部分可以考虑修改的更加严谨。

 

 

五、总结

  经过这三次的题目集练习,我加深了对正则表达式的理解,在多次的练习中我也能够在不同的场景下对其进行较好的运用。并且通过练习题目,我尝试了继承、接口与多态的具体使用方法,之前一直停留在理论层次而没有进行实践。我也明白了不同聚合的优劣势,能够更加理解聚合对于参数的赋值与调用。但是许多方法对我来说还是初次见面,使用起来并不熟悉,就譬如ArrayList的各个方法和Map键值对,都是我查阅相关用法才开始写的,写的东西覆盖面多了就越来越觉得自己会的东西太少,虽然平时写作业压力不大,但还是要继续努力不能停留在写个作业的水平上。之后的题目集要更加认真的对待。

posted @ 2021-11-13 10:49  LoseYoung  阅读(119)  评论(0)    收藏  举报