[Java]题目集4-6总结

[Java]题目集4-6总结

一.前言:

总结三次题目集的知识点、题量、难度等情况:

  首先:对于本三次题目集,主要大幅度考察的内容为Java面向对象的三大特征:

1.继承性

2.多态性

3.封装性

  a.其中,对继承性考察的主要方式是定义的多个类要用继承父类的方法,并遵守继承的主要要求(最重要的一点即——子类重写父类的方法,并在父类中的默认方法必须要自己写,否则子类继承时会报错);

  b.而对于多态性的考察主要是在类中需要写重载方法,即判断图形合理性时会有判断三角形、圆形、正方形等不同数据的检测,这是就需要运用方法重载来进行实现,其中方法重载也是多态性的一点体现;

  c.对于封装性,从刚开始接触java的时候便体现的淋漓尽致了,封装性基本在本三次题目集中都有考察,因为它是java面向对象语言的灵魂,所有的类,类中的私有属于,方法等都是语言封装性的体现。其中题目集6的7-6实现图形接口及多态性需要运用到接口,接口也是封装性的一大特色,运用接口可以使程序更加简便,灵活,且便于后期的维护与功能修改。

  考察例题:

  题目集4:

      7-1 水文数据校验及处理

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

      7-3 图形继承

  题目集5:

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

  题目集6:

      7-5 图形继承与多态

      7-6实现图形接口及多态性

 

  其次:这三次题目集也针对“正则表达式”的理解与运用进行了考察,而且还有一定的难度,如7-1 水文数据校验及处理,7-4 统计Java程序中关键词的出现次数以及题目集6的诸多小题均是对正则表达式的考察,对正则表达式的考察一定意味着对字符串相关函数的考察,字符串匹配成功后的处理,比如字符串换错Double类型等进行合理化的运算或者分割。

  最后:本次题目集最大的收获是“7-4 统计Java程序中关键词的出现次数”该题的算法,需要用哈希算法,虽然没能做出来,但是对大佬们写出来了的程序进行分析,发现了哈希算法并认识到了哈希算法的巧妙性与其时间梯度的简单性。

 

 

 

设计与分析:

    题目集4  7-2 日期问题面向对象设计(聚合一)

 

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,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且输入均有效,输出格式如下:
    year-month-day
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year-month-day
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    天数值
     

 

输入样例1:

 

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

 

3 2014 2 14 2020 6 14

 

 

 

输出样例1:

 

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

 

2312

 

 

 

输入样例2:

 

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

 

2 1935 2 17 125340

 

 

 

输出样例2:

 

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

 

1591-12-17

 

 

 

输入样例3:

 

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

 

1 1999 3 28 6543

 

 

 

输出样例3:

 

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

 

2017-2-24

 

 

 

输入样例4:

 

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

 

0 2000 5 12 30

 

 

输出样例4:

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

Wrong Format

源代码:
import java.util.Scanner;
class Shape{
    Shape(){
        //System.out.println("Constructing Shape");
    }
    public double getArea(){
        return 0.0;
    }
}

class Ball extends Circle{
    Ball(){
       // System.out.println("Constructing Ball");
    }
    @Override
    public double getArea() {
        return super.getArea()*4;
    }
    public double getVolume(){
        return getArea()/3*getRadius();
    }
}

class Box extends Rectangle{
    Box(){
       // System.out.println("Constructing Box");
    }
    private double height;

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
    @Override
    public double getArea() {
        return 2*(getHeight()*getLength()+getHeight()*getWidth()+getLength()*getWidth());
    }
    public double getVolume(){
        return super.getArea()*height;
    }
}

public class Main {
    public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    Circle circle =new Circle();
    circle.setRadius(5);
    circle.getArea();
    int year = 0;
    int month = 0;
    int day = 0;
    

    int choice = input.nextInt();

    if (choice == 1) { // test getNextNDays method
        
        
         Rectangle rectangle =new Rectangle();
         rectangle.setLength(30);
         rectangle.setWidth(20);
         rectangle.getArea();
         
        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.println(date.getNextNDays(m).showDate());
    } else if (choice == 2) { // test getPreviousNDays method
        
        Ball ball =new Ball();
        ball.setRadius(100);
        ball.getArea();
        ball.getVolume();
        
 
        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.println(date.getPreviousNDays(n).showDate());
    } else if (choice == 3) {    //test getDaysofDates method
        
        
        Box box =new Box();
        box.setLength(50);
        box.setWidth(60);
        box.setHeight(80);
        box.getArea();
        box.getVolume();
        
        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(fromDate.getDaysofDates(toDate));
        } else {
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }
    else{
        System.out.println("Wrong Format");
        System.exit(0);
    }
}
}

class Circle extends Shape{
    Circle(){
        //System.out.println("Constructing Circle");
    }
    private double radius;

    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{
    Rectangle(){
        //System.out.println("Constructing Rectangle");
    }
    private double width;
    private double length;

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    @Override
    public double getArea() {
        return length*width;
    }
}


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 < 1900 || year > 2050) return false;
    if (month < 1 || month > 12) return false;
    if(day<1||day>31) 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;
}
}
  本题难度不算大,主要是考察对日期数据的继承,本题的继承是从年份开始从上往下依次继承,因此,在
最后的最小子类中,不在需要重新定义父类的变量了,可以直接继承父类的变量与方法,简化了书写程序的步
骤性,而其中对一些数据的处理也要运用一定的技巧才能够实现。
    以下为SourceMonitor 的生成报表:




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

参考题目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:值
     

输入样例1:

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

3 2014 2 14 2020 6 14
 

输出样例1:

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

The days between 2014-2-14 and 2020-6-14 are:2312
 

输入样例2:

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

2 1834 2 17 7821
 

输出样例2:

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

1834-2-17 previous 7821 days is:1812-9-19
 

输入样例3:

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

1 1999 3 28 6543
 

输出样例3:

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

1999-3-28 next 6543 days is:2017-2-24
 

输入样例4:

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

0 2000 5 12 30
 

输出样例4:

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

Wrong Format
源代码:
import java.util.Scanner;
class Shape{
    Shape(){
        //System.out.println("Constructing Shape");
    }
    public double getArea(){
        return 0.0;
    }
}

class Ball extends Circle{
    Ball(){
       // System.out.println("Constructing Ball");
    }
    @Override
    public double getArea() {
        return super.getArea()*4;
    }
    public double getVolume(){
        return getArea()/3*getRadius();
    }
}

class Box extends Rectangle{
    Box(){
       // System.out.println("Constructing Box");
    }
    private double height;

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
    @Override
    public double getArea() {
        return 2*(getHeight()*getLength()+getHeight()*getWidth()+getLength()*getWidth());
    }
    public double getVolume(){
        return super.getArea()*height;
    }
}

public class Main{
    public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    Circle circle =new Circle();
    circle.setRadius(5);
    circle.getArea();
    int year = 0;
    int month = 0;
    int day = 0;
    

    int choice = input.nextInt();

    if (choice == 1) { // test getNextNDays method
        
        
         Rectangle rectangle =new Rectangle();
         rectangle.setLength(30);
         rectangle.setWidth(20);
         rectangle.getArea();
         
        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
        
        Ball ball =new Ball();
        ball.setRadius(100);
        ball.getArea();
        ball.getVolume();
        
 
        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
        
        
        Box box =new Box();
        box.setLength(50);
        box.setWidth(60);
        box.setHeight(80);
        box.getArea();
        box.getVolume();
        
        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 Circle extends Shape{
    Circle(){
        //System.out.println("Constructing Circle");
    }
    private double radius;

    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{
    Rectangle(){
        //System.out.println("Constructing Rectangle");
    }
    private double width;
    private double length;

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    @Override
    public double getArea() {
        return length*width;
    }
}


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;
}
}
以下为SourceMonitor 的生成报表:







  题目总结:针对这两次功能相同但是结构不一样的题目的总结是,前者是从上到下依次继承,其函数的耦合度较高,好处是可以让最后的那
一个子类可以不需要重写父类的参数与方法,而后者则是定义年、月、日,分别视它们为单独的一个父类,而最后的那一个子类,去继承这些父
类,也解决了不需要重写父类方法、参数的问题,而且相较于前者,后者的耦合度较低,方便代码的修改与查改,不会说一错全错,对于面向对
象语言,耦合度越低越方便我们增加、删改代码,也能让程序相互独立,便于修改。所以对于后者是应该我们大家学习的写法。



    题目集4  7-3 图形继承

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

  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;
class Shape{
    Shape(){
        System.out.println("Constructing Shape");
    }
    public double getArea(){
        return 0.0;
    }
}

class Circle extends Shape{
    Circle(){
        System.out.println("Constructing Circle");
    }
    private double radius;

    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{
    Rectangle(){
        System.out.println("Constructing Rectangle");
    }
    private double width;
    private double length;

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    @Override
    public double getArea() {
        return length*width;
    }
}

class Ball extends Circle{
    Ball(){
        System.out.println("Constructing Ball");
    }
    @Override
    public double getArea() {
        return super.getArea()*4;
    }
    public double getVolume(){
        return getArea()/3*getRadius();
    }
}

class Box extends Rectangle{
    Box(){
        System.out.println("Constructing Box");
    }
    private double height;

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
    @Override
    public double getArea() {
        return 2*(getHeight()*getLength()+getHeight()*getWidth()+getLength()*getWidth());
    }
    public double getVolume(){
        return super.getArea()*height;
    }
}

class cheakMethod{
    //判断输入的进入程序的数据是否合理
    public Boolean cheakKey(int n){
        boolean result =false;
        if(n>=1&&n<=4){
            result =true;
        }else{
        System.out.println("Wrong Format");}
        return result;
    }
    //判断输入的测试数据是否合理
    public Boolean cheak(double n ){
        boolean result = false;
        if(n>=0){
            result =true;
        }else{
        System.out.println("Wrong Format");}
        return result;
    }
    public Boolean cheak(double n ,double m){
        boolean result = false;
        if(n>=0&&m>=0){
            result =true;
        }else{
        System.out.println("Wrong Format");}
        return result;
    }

    public Boolean cheak(double n,double m,double x ){
        boolean result = false;
        if(n>=0&&m>=0&&x>=0){
            result =true;
        }else{
        System.out.println("Wrong Format");}
        return result;
    }

}


public class Main {
    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        int keyNum =sc.nextInt();
        cheakMethod ck =new cheakMethod();
        if(ck.cheakKey(keyNum)){
            switch (keyNum){
                case 1:
                    double r =sc.nextDouble();
                    if(ck.cheak(r)){
                        Circle circle =new Circle();
                        circle.setRadius(r);
                        System.out.println("Circle's area:"+String.format("%.2f",circle.getArea()));
                    }
                    break;
                case 2:
                    double leagth =sc.nextDouble();
                    double width =sc.nextDouble();
                    if(ck.cheak(leagth,width)){
                        Rectangle rectangle =new Rectangle();
                        rectangle.setLength(leagth);
                        rectangle.setWidth(width);
                        System.out.println("Rectangle's area:"+String.format("%.2f",rectangle.getArea()));
                    }
                    break;
                case 3:
                    double radix =sc.nextDouble();
                    if(ck.cheak(radix)){
                        Ball ball =new Ball();
                        ball.setRadius(radix);
                        System.out.println("Ball's surface area:"+String.format("%.2f",ball.getArea()));
                        System.out.println("Ball's volume:"+String.format("%.2f",ball.getVolume()));
                    }
                    break;
                case 4:
                    double a =sc.nextDouble();
                    double b =sc.nextDouble();
                    double c =sc.nextDouble();
                    if(ck.cheak(a,b,c)){
                        Box box =new Box();
                        box.setLength(a);
                        box.setWidth(b);
                        box.setHeight(c);
                        System.out.println("Box's surface area:"+String.format("%.2f",box.getArea()));
                        System.out.println("Box's volume:"+String.format("%.2f",box.getVolume()));
                    }
                    break;
            }
        }
    }
}

7-5 图形继承与多态

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

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.Arrays;
import java.util.Scanner;

class Shape{
    //计算总面积
    //ArrayList list =new ArrayList();
    public double areaSum(ArrayList list){
        double areasum=0;
        Double[] array = new Double[list.size()];
        list.toArray(array);
        for (int i = 0; i <array.length ; i++) {
            areasum=areasum+array[i];
        }
        return areasum;
    }
    //打印面积
    public void printArea(ArrayList list){
        Double[] array = new Double[list.size()];
        list.toArray(array);
        for (int i = 0; i <array.length ; i++) {
            System.out.print(String.format("%.2f",array[i])+" ");
        }
    }

    //排序各个面积并打印
    public void sortArea(ArrayList list){
        Double[] array = new Double[list.size()];
        list.toArray(array);
        Arrays.sort(array);
        /*for (int i = 0; i < list.size(); i++) {
            System.out.print(String.format("%.2f",AreaSum[i])+" ");
        }*/
        for (int i = 0; i <array.length ; i++) {
            System.out.print(String.format("%.2f",array[i])+" ");
        }
    }
    //面积方法的多态性表述
   public double getArea(double radius){
       double area=0;
       area=Math.PI*radius*radius;
       return area;
   }
   public double getArea(double width,double length){
       double area=0;
       area=width*length;
       return area;
   }
   public double getArea(double side1,double side2,double side3){
       double area=0;
       double s =(side1+side2+side3)/2f;
       double S = (float) Math.sqrt(s*(s-side1)*(s-side2)*(s-side3));
       return S;
   }


   //数据检测方法的多态性表述
   public Boolean vaildate(double radius){
       if(radius<=0)
           return false;
       else
           return true;

    }

    public Boolean vaildateInput(int input){
        if(input<0)
            return false;
        else
            return true;

    }

    public Boolean vaildate(double width,double length){
       if(width<0||length<0)
           return false;
       else
           return true;
    }

    public Boolean vaildate(double side1,double side2,double side3){
       if(side1<0||side2<0||side3<0){
           return false;
       }
       else if(side1+side2>side3&&side1+side3>side2&&side2+side3>side3){
           return true;}
           else
           return false;
    }

}

class Circle extends Shape{
    double radius;
}

class Rectangle extends Shape{
    double width,length;
}

class Triangle extends Shape{
    double side1,side2,side3;
}



public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Shape shape = new Shape();
        int shape1 = scanner.nextInt();
        int shape2 = scanner.nextInt();
        int shape3 = scanner.nextInt();
        int sum =shape1+shape2+shape3;
        ArrayList list =new ArrayList();
        //Double[] AreaSum = new Double[sum];
        if (shape.vaildateInput(shape1) && shape.vaildateInput(shape2) && shape.vaildateInput(shape3)) {
            if (shape1>0) {
                Circle circle = new Circle();
                for (int i = 0; i < shape1; i++) {
                    circle.radius = scanner.nextDouble();
                    if(shape.vaildate(circle.radius)){
                    list.add(circle.getArea(circle.radius));
                    }else {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }

                }
            }
            if (shape2>0) {
                Rectangle rectangle = new Rectangle();
                for (int i = 0; i < shape2; i++) {
                    rectangle.length = scanner.nextDouble();
                    rectangle.width = scanner.nextDouble();
                    if(shape.vaildate(rectangle.width, rectangle.length)){
                        list.add(rectangle.getArea(rectangle.width, rectangle.length)) ;
                    }else {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                }
            }
            if (shape3>0) {
                Triangle triangle = new Triangle();
                for (int i = 0; i < shape3; i++) {
                    triangle.side1 = scanner.nextDouble();
                    triangle.side2 = scanner.nextDouble();
                    triangle.side3 = scanner.nextDouble();
                    if(shape.vaildate(triangle.side1, triangle.side2, triangle.side3)){
                        list.add (triangle.getArea(triangle.side1, triangle.side2, triangle.side3)) ;
                    }else {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                }
            }
            //System.out.println(shape.list);

            if(shape1==0&&shape2==0&&shape3==0){
                System.out.println("Original area:");
                System.out.println("");
                System.out.println("Sum of area:0.00");
                System.out.println("Sorted area:");
                System.out.println("");
                System.out.println("Sum of area:0.00");

            }else {
                System.out.println("Original area:");
                shape.printArea(list);
                System.out.println();
                System.out.println("Sum of area:" + String.format("%.2f",shape.areaSum(list)));
                System.out.println("Sorted area:");
                shape.sortArea(list);
                System.out.println();
                System.out.println("Sum of area:" + String.format("%.2f",shape.areaSum(list)));
            }
        }else
            System.out.println("Wrong Format");
    }
}
7-6 实现图形接口及多态性

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

类图.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;

class CircleA implements getAreaA{
    double r;
    @Override
    public double getArea(double width) {
        double area=Math.PI*r*r;
        return area;
    }
}
class RectangleA implements getAreaA{
    double width,length;
    @Override
    public double getArea(double width) {
        double area = this.width * this.length;
        return area;
    }
}
interface getAreaA{
    double getArea(double width);
}

public class Main {
    public static void main(String[] args) {
        CircleA circle = new CircleA();
        RectangleA rectangle = new RectangleA();
        Scanner scanner =new Scanner(System.in);
        circle.r=scanner.nextDouble();
        rectangle.width=scanner.nextDouble();
        rectangle.length=scanner.nextDouble();
        if(circle.r<=0||rectangle.length<=0||rectangle.width<=0){
            System.out.println("Wrong Format");
        }else {
            System.out.println(String.format("%.2f",circle.getArea(circle.r)));
            System.out.println(String.format("%.2f",rectangle.getArea(rectangle.width)));
        }
    }
}

    题目总结:通过三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)的题目,需要
运用的技术也是越来越多,如第一题要用到封装与继承,而第二题开始就要运用多态对数据的合理化进行检验了,
而第三题则是要用到接口,而且每一题的算法结构也有稍微的不一样,其中印象最深刻的是对接口的运用,接口的
使用也有一点类似子类方法的使用,都是需要重写待接口的方法,而且接口不能够直接创建使用。

    
接口的好处:
以前对接口和抽象类,总是模糊,不知道什么时候用接口,什么时候用抽象类。通过查阅一些资料,加上一些自己
的理解,现在整理如下:接口和抽象类有很大的相似性,甚至可以相互替换,因此很多开发者在进行开发时对于接
口和抽象类的选择显得比较随意。其实,他们是有区别的。对于接口的作用,在一些小的项目上,很难看出其发挥
的优势。这就使一些经常的做小项目的开发人员,做时间久了就感觉不到它有什么好的,有时候写起来还麻烦,干
脆不用了。其实,在一些大项目上,接口的作用是发挥地相当的明显的。比如:如果你开发业务逻辑代码,当你好
不容易的实现了它全部的功能,突然用户需求要改,你在修改你代码的同时,调用你代码的其它人也会改,如果代
码关联性强的话,会有很多人都要改动代码,这样一来二去,程序会变得相当的不稳定,而且可能还会出现更多的
新Bug,所有人都可能会陷入混乱。但如果使用接口的话,在你使用它之前,就要想好它要实现的全部功能(接口实
际上就是将功能的封装)。确定下这个接口后,如果用户需求变了,你只要重新写它的实现类,而其它人只会调用
你的接口,他不管你是怎么实现的,它只需要接口提供的功能。这样,很可能只需要把你的代码修改就可以了,其
他人什么都不用做。同时:这样做的话,使得开发人员能够分工明确,只要确定下来接口了,就可以同时进行开发
,提高开发效率。另外,使用接口还有使用方便,可读性强,结构清晰等优点。当然,我说的这些也可能是浅层面
的,在其他方面还有很多的好处。抽象类:可以有抽象方法,也可以有方法的实现。抽象类不一定有抽象方法,而
有抽象方法的类一定是抽象类。抽象类不能实例化。接口:只有方法体的声明,没有方法实现。一个类可以实现多
个接口,但只能继承一个抽象类。在项目上,我们一般的做法是:最上层为接口,中间层次为抽象类,往下就是我
们的实现类。为什么我们会在中间加上抽象类呢,就是为了提高代码的可重用性,你可以在抽象类里提炼出一些公
用的已经实现的方法,那么底下那些实现类只要继承它也就继承了这些方法。

题目集5 7-4 统计Java程序中关键词的出现次数

编写程序统计一个输入的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.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class p4 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);

String a;
StringBuilder ss=new StringBuilder();
Map<String, Integer> map=new HashMap<String, Integer>();
//56个关键字
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"

};

int j=0;
for(int i=0;;i++) {
a=input.nextLine();
if(a.equals("exit"))
break;
if(a.matches("(.*)//(.*)"))//匹配注释内容并进行分割
{String b[]=a.split("//");
ss.append(b[0]+" ");
//ss.append('\n');
}
else
{ss.append(a+" ");
//ss.append('\n');
}
}
int count=0;
String s=ss.toString();
// System.out.println(s);
Pattern p=Pattern.compile("\"(.*?)\"");//匹配引号里面的内容并删除
Matcher m=p.matcher(s);
while(m.find()){
s=s.replace(m.group()," ");
p=Pattern.compile("\"(.*?)\"");
m=p.matcher(s);
}
p=Pattern.compile("/\\**(.*?)/");//匹配不同行的大篇幅注释并删除
m=p.matcher(s);
while(m.find()){
s=s.replace(m.group()," ");
// p=Pattern.compile("/\\*(.*?)\\*/");
m=p.matcher(s);
}
// System.out.println(s);
if(s.isEmpty())
{System.out.println("Wrong Format");
System.exit(0);
}
//删除特殊的符号
s=s.replace("["," ");
s=s.replace("]"," ");
s=s.replace("-"," ");
s=s.replace("*"," ");
s=s.replace("/"," ");
s=s.replace("+"," ");
s=s.replace(">"," ");
s=s.replace("="," ");
s=s.replace("!"," ");
s=s.replace(":"," ");
s=s.replace("\\"," ");
s= s.replaceAll("[^a-zA-Z]", " ");

String []s1=s.split("[ ' ']");//匹配单引号并删除(单引号)
for(int i=0;i<s1.length;i++)
{//System.out.println(s1[i]);
for( j=0;j<key.length;j++)
if(s1[i].equals(key[j]))
{
map.put(key[j], 0);
}
}
for( int i = 0;i<s1.length;i++)
{
for( j=0;j<key.length;j++)
if(s1[i].equals(key[j]))
{ count=map.get(key[j]);
map.put(key[j], count+1);
}
}
Set set=map.keySet();
Object[] arr=set.toArray();
Arrays.sort(arr);
for(Object k:arr){
System.out.println(map.get(k)+"\t"+k);
}
}
}

    本题由于没有学习到哈希算法的精髓,无法自己写出,以上为网上大牛的写法,通过对其代码的
分析也理解到了哈希算法的简便性与优越性,其中哈希算法总结如下:
  • 正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。
  • 逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。
  • 输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。
  • 冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。即对于任意两个不同的数据块,其hash值相同的可能性极小;对于一个给定的数据块,找到和它hash值相同的数据块极为困难。

但在不同的使用场景中,如数据结构和安全领域里,其中对某一些特点会有所侧重。






五:总结:
    对三次题目集中用到的正则表达式技术的分析总结:
    1.对于三次题目集都有不同程度上的对正则表达式的运用,其中有单纯的对数字的检验(如QQ号的合理性
检验),也有单纯对字符串的检验(如字符串排序检验),也有二者中和,数字与字母的检验(如验证码的合理检
验),难度依次增大,也更加加深了我们对字符串的理解与运用,更是合理的掌握了如何正确书写有目的要求的正
则表达式与对其的运用。

    2.通过这三次的题目集也更好的理解了JAVA面向对象语言的三大特征:封装、继承、多态。
    能够通过对类的使用,类的相互继承、接口的使用等使得程序的耦合度变低,从而实现对代码的查验与修
改,使得代码更加合乎面向对象。

    3.通过对“7-4 统计Java程序中关键词的出现次数”中的哈希算法,更加的理解到了哈希算法的简便性与
其功能实现的简单方便,解决了依靠传统方法无法解决的问题,而哈希算法的时间维度与算法难度都比正常的FOR循
环减低了一个层次。

    总的来说,这三次的题目集难度适中,且有层次性,能让我们循序渐进的增加对面向对象语言三大特征的理
解与合理运用,得出有一下的结论:
面向对象的三大基本特征:
封装,继承,多态

封装的好处:
(1)保证数据的安全性
(2)提供清晰的对外接口
(3)类内部实现可以任意修改,不影响其它类

继承是指这样一种能力:
通过继承创建的新类称为“子类”或“派生类”
被继承的类称为“基类”、“父类”或“超类”。
要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。

继承概念的实现方式有三类:实现继承、接口继承和可视继承。

实现多态,有二种方式,覆盖,重载。
真正和多态相关的是“覆盖”。
多态的作用:保证类的实例的某一属性时的正确调用。



 

 

    

posted @ 2021-04-22 11:07  谁说码农没头发  阅读(69)  评论(0)    收藏  举报