题目集4~6的总结性Blog

前言:

本次作业少数题目难度较大,比如水文处理和统计Java关键词次数,大部分题目难度都适中,题量适中。题目主要考察了正则表达式技术,字符串的处理,三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)。

 

 

目录:(Java题目集)

     1.题目集四(7-2)

     2.题目集五(7-4)

     3.题目集五(7-5)

     4.题目集四(7-3)

     5.题目集六(7-5)

     6.题目集六(7-6)

 

1.题目集四(7-2)

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

 

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

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

输入格式:

有三种输入方式(以输入的第一个数字划分[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

 

题目分析:定义一个类Dateutil,在类里定义年,月,日三个属性,在类中需要定义一个判断闰年的方法,一个判断输入日期是否输入正确的方法,一个求下n天的方法,一个求前n天的方法,一个求两日期相差天数的方法,一个判断两日期大小的方法。

 

主要方法代码:

判断闰年

public boolean isLeapYear(int year)

        {

            if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)

                return true;

            else

                return false;

        }

//检测数据是否合法

        public boolean checkInputValidity() {

            if (year < 1900 || year > 2050 || month < 1 || month > 12)

                return false;

            if(month!=2){

                if(day<1||day>a[month])

                    return false;

            }

            if(month==2){

                if(isLeapYear(year)==true){

                    if (day<1||day>29)

                        return false;

                }

                else

                if(day<1||day>28)

                    return false;

            }

            return true;

        }

//比较两个日期的大小

        public boolean compareDates(DateUtil date) {

            if (year > date.year)

                return true;

            else if (year == date.year) {

                if (month > date.month)

                    return true;

                else if (month == date.month) {

                    if (day > date.day)

                        return true;

                    if (day < date.day)

                        return false;

                } else

                    return false;

            } else

                return false;

            return false;

        }

//求下n天

public DateUtil getNextNDays(int n) {

            int y=year;

            int m=month;

            int d=day;

            for (int i=0;i<n;i++) {

                if (isLeapYear(y))

                    a[2] = 29;

                else

                    a[2] = 28;

                d+=1;

                if (d>a[m]) {

                    d=1;

                    m++;

                }

                if (m>12) {

                    y++;

                    m=1;

                    d=1;

                }

            }

            return new DateUtil(y,m,d);

        }

//求前n天

        public DateUtil getPreviousNDays(int n) {

            int year=this.year;

            int month=this.month;

            int day=this.day;

            for (int i=0;i<n;i++) {

                day--;

                if (isLeapYear(year))

                    a[2] = 29;

                else

                    a[2] = 28;

                if(day<1) {

                    month--;

                    if (month<1) {

                        month=12;

                        year--;

                    }

                    day=a[month];

                }

            }

            return new DateUtil(year, month, day);

        }

//求两日期相差天数

        public int getDaysofDates(DateUtil date){

            DateUtil dateUtil1 = this; // 小

            DateUtil dateUtil2 = date; // 大

             if (this.compareDates(date)) {

            dateUtil1 = date;

            dateUtil2 = this;

        }

            int sum=0,cnt=0,i,n=0;

            i=dateUtil1.month;

            int j=dateUtil1.year;

            if(j!=dateUtil2.year){

                sum+=a[i]-dateUtil1.day;

                i++;

                while(j!=dateUtil2.year){

                    if (isLeapYear(j))

                        a[2] = 29;

                    else

                        a[2] = 28;

                    while(i<=12){

                        sum+=a[i];

                        i++;

                    }

                    i=1;

                    j++;

                }

                if (isLeapYear(j))

                    a[2] = 29;

                else

                    a[2] = 28;

                while(i!=dateUtil2.month){

                    sum+=a[i];

                    i++;

                }

                sum+=dateUtil2.day;

            }

            if(dateUtil1.year==dateUtil2.year){

                if(dateUtil1.month==dateUtil2.month)

                    sum+=dateUtil2.day-dateUtil1.day;

                else{

                    sum+=a[dateUtil1.month]-dateUtil1.day;

                    dateUtil1.month++;

                    while(dateUtil1.month!=dateUtil2.month){

                        sum+=a[dateUtil1.month];

                        dateUtil1.month++;

                    }

                    sum+=dateUtil2.day;

                }

            }

            return sum;

        }

 

2.题目集五(7-4)

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

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

 

题目分析:本题要求统计Java关键词的出现次数,首先进行判断输入是否为空,将Java中所有关键词放入一个数组里,将代码与注释分开,将输入的字符串要与其他代码分开,之后统计关键字出现的次数,将其进行升序排列输出。

 

主要代码:

//输入代码及将注释与代码分开

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');

}

}

//运用正则表达式进行判断

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

       }

统计各关键词的出现次数:

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

}

}

 

3.题目集五(7-5)

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

 

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

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

题目分析:本题与之前题目类似,输出格式有所改变,题目总体代码所需改变不大,方法可沿袭之前所需的方法,输出的方法需要改动。

主要改动代码:

switch(a){

            case 1:

                year=input.nextInt();

                month=input.nextInt();

                day=input.nextInt();

                DateUtil dateUtil=new DateUtil(year,month,day);

                n=input.nextInt();

                if(dateUtil.checkInputValidity()==false||n<0){

                    System.out.println("Wrong Format");

                    System.exit(0);

                }

                System.out.println(year+"-"+month+"-"+day+" next "+n+" days is:"+dateUtil.getNextNDays(n).showDate());

                break;

            case 2:

                year=input.nextInt();

                month=input.nextInt();

                day=input.nextInt();

                DateUtil dateUtil1=new DateUtil(year,month,day);

                n=input.nextInt();

                if(dateUtil1.checkInputValidity()==false||n<0){

                    System.out.println("Wrong Format");

                    System.exit(0);

                }

                dateUtil1.getPreviousNDays(n);

                DateUtil temp=dateUtil1.getPreviousNDays(n);

                System.out.println(year+"-"+month+"-"+day+" previous "+n+" days is:"+temp.showDate());

                break;

            case 3:

                year=input.nextInt();

                month=input.nextInt();

                day=input.nextInt();

                int year1=input.nextInt();

                int month1=input.nextInt();

                int day1=input.nextInt();

                DateUtil dateUtilpast=new DateUtil(year,month,day);

                DateUtil dateUtil1now=new DateUtil(year1,month1,day1);

                if(dateUtilpast.checkInputValidity()==false||dateUtil1now.checkInputValidity()==false){

                    System.out.println("Wrong Format");

                    System.exit(0);

                }

                if(dateUtilpast.compareDates(dateUtil1now)==false)

                    System.out.println("The days between "+year+"-"+month+"-"+day+" and "+year1+"-"+month1+"-"+day1+" are:"+dateUtilpast.getDaysofDates(dateUtil1now));

                else

                    System.out.println("The days between "+year+"-"+month+"-"+day+" and "+year1+"-"+month1+"-"+day1+" are:"+dateUtilpast.getDaysofDates(dateUtil1now));

                break;

        }

两种日期类聚合设计的优劣比较:

优:第一题中只需定义一个类,类中定义三个属性,更方便进行方法的构造。第二题定义四个类,在每个类类中定义各自的方法,出错率更低。

劣:第二种方法定义类太多,容易产生逻辑上的错误,但更方便进行两个日期之间的比较,第一种进行日期比较更复杂。

 

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

 

题目分析:本题要求定义四个类,其中定义一个父类Shape,其他类均定义为Shape的子类,其中父类需写一个求面积的方法,其他子类需要继承这个方法并重写父类的方法。其余子类还需写一个判断输入数据是否正确的方法。

 

主要代码:

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner input=new Scanner(System.in);

        int a=input.nextInt();

        if(a<1||a>4){

            System.out.println("Wrong Format");

            System.exit(0);

        }

        switch(a){

            case 1:

                double radius=input.nextDouble();

                if(radius<=0){

                    System.out.println("Wrong Format");

                    System.exit(0);

                }

                else{

                    Circle circle=new Circle();

                    circle.setRadius(radius);

                    System.out.println("Circle's area:"+String.format("%.2f",circle.getArea()));

                }

                break;

            case 2:

                double width=input.nextDouble();

                double length=input.nextDouble();

                if(width<=0||length<=0){

                    System.out.println("Wrong Format");

                    System.exit(0);

                }

                else{

                    Rectangle retangle=new Rectangle();

                    retangle.setter(width,length);

                    System.out.println(String.format("Rectangle's area:%.2f",retangle.getArea()));

                }

                break;

            case 3:

                double radius1=input.nextDouble();

                if(radius1<=0){

                    System.out.println("Wrong Format");

                    System.exit(0);

                }

                else{

                    Ball ball=new Ball();

                    System.out.println(String.format("Ball's surface area:%.2f",ball.getArea(radius1)));

                    System.out.println(String.format("Ball's volume:%.2f",ball.getVolume(radius1)));

                }

                break;

            case 4:

                double width1=input.nextDouble();

                double length1=input.nextDouble();

                double height=input.nextDouble();

                if(width1<=0||length1<=0||height<=0){

                    System.out.println("Wrong Format");

                    System.exit(0);

                }

                else{

                    Box box=new Box();

                    box.getHeight(height);

                    System.out.println("Box's surface area:"+String.format("%.2f",box.getArea(width1,length1)));

                    System.out.println("Box's volume:"+String.format("%.2f",box.getVolume(width1,length1)));

                }

                break;

        }

    }

    static class Shape{

        public Shape(){

            System.out.println("Constructing Shape");

        }

        public double getArea(){

            return 0;

        }

    }

         //圆类

    static class Circle extends Shape{

        private double radius;

        public Circle()

        {

            System.out.println("Constructing Circle");

        }

        //获取半径

        public void setRadius(double radius) {

            this.radius = radius;

        }

        public double getRadius(){

            return radius;

        }

        //重写父类方法

        @Override

        public double getArea() {

            double sum=0;

            sum=Math.pow(radius,2)*Math.PI;

            return sum;

        }

    }

        //矩形类

    static class Rectangle extends Shape{

        private double width;

        private double length;

        public Rectangle(){

            System.out.println("Constructing Rectangle");

        }

 

        public void setter(double width,double length){

            this.width=width;

            this.length=length;

        }

        public double getWidth(){

            return width;

        }

 

            public double getLength(){

                return length;

            }

            @Override

            public double getArea() {

                return width*length;

            }

        }

        //球类

    static class Ball extends Circle{

        public Ball(){

            System.out.println("Constructing Ball");

        }

 

            public double getArea(double radius) {

                double sum=0;

                sum=Math.pow(radius,2)*Math.PI*4;

                return sum;

            }

            public double getVolume(double radius){

                double sum=0;

                sum=Math.pow(radius,3)*4/3*Math.PI;

                return sum;

            }

        }

        static class Box extends Rectangle{

        private double height;

        public Box(){

            System.out.println("Constructing Box");

        }

 

        public void getHeight(double heigth){

            this.height=heigth;

        }

 

            public double getArea(double width,double length) {

               double sum=2*width*length+2*width*height+2*length*height;

               return sum;

            }

            public double getVolume(double width,double length){

                return width*length*height;

            }

        }

}

 

5.题目集六(7-5)

题目要求:参考题目集 04 中 7-3 中图形类的继承层次结构,本次作业重点研究平面图形相关的处理方法。 图形类的继承层次结构如下图所示。 getArea()方法为抽象方法,功能为求得图形的面积;validate()方法也为抽象方法,对图形的属 性进行合法性校验;toString()继承自 Object,功能为输出图形的面积信息,其格式参考输出示例。 另外,此类图为示意图,具体属性及方法请大家自行完善。同时,如果要新增类,请自行设计。从键盘首先输入三个整型值(例如 a b c),分别代表想要创建的 Circle、Rectangle 及 Triangle 对 象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多 个空格或回车分隔。

 

题目分析:首先定义类与之前相同,且类中的方法也相同。首先将图形的数量a,b,c先输入,先判断图形数量输入是否正确,分别定义出三个图形的数组,通过循环进行数据的输入,再通过循环判断输入数据是否正确,将各图形的面积通过方法计算出来并通过一个数组保存并输出,再将其排序输出。

 

代码:

import java.math.BigDecimal;

import java.text.DecimalFormat;

import java.util.*;

public class Main {

    public static void main(String[] args) {

        java.util.Scanner input = new java.util.Scanner(System.in);

        int a=input.nextInt();

        int b=input.nextInt();

        int c=input.nextInt();

        if(a<0||b<0||c<0){

            System.out.println("Wrong Format");

            System.exit(0);

        }

        int i,j,cnt;

        double temp,sum=0;

        cnt=a+b+c;

        double[] s=new double[cnt];

        Circle[] circles=new Circle[a];

        Rectangle[] rectangles=new Rectangle[b];

        Triangle[] triangles=new Triangle[c];

        for(i=0;i<a;i++){

            circles[i]=new Circle();

            circles[i].radius=input.nextDouble();

        }

        for(i=0;i<b;i++){

            rectangles[i]=new Rectangle();

 

            rectangles[i].length=input.nextDouble();

            rectangles[i].width=input.nextDouble();

        }

        for(i=0;i<c;i++){

            triangles[i]=new Triangle();

            triangles[i].side1=input.nextDouble();

            triangles[i].side2=input.nextDouble();

            triangles[i].side3=input.nextDouble();

        }

 

        for(i=0;i<a;i++){

            if(circles[i].validate()==false){

                System.out.println("Wrong Format");

                System.exit(0);

            }

            BigDecimal z  =   new   BigDecimal(circles[i].getArea());

            s[i] = z.setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue();

            sum+=s[i];

        }

        for(i=0;i<b;i++){

            if(rectangles[i].validate()==false){

                System.out.println("Wrong Format");

                System.exit(0);

            }

            BigDecimal z  =   new   BigDecimal(rectangles[i].getArea());

            s[a+i] = z.setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue();

            sum+=s[a+i];

        }

        for(i=0;i<c;i++){

            if(triangles[i].validate()==false){

                System.out.println("Wrong Format");

                System.exit(0);

            }

            BigDecimal z  =   new   BigDecimal(triangles[i].getArea());

            s[a+b+i] = z.setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue();

            sum+=s[a+b+i];

        }

        System.out.println("Original area:");

        for(i=0;i<cnt;i++){

            System.out.printf("%.2f ",s[i]);

        }

        System.out.print("\n");

        System.out.printf("Sum of area:%.2f\n",sum);

        for(i=0;i<cnt-1;i++){

            for(j=i+1;j<cnt;j++){

                if(s[j]<s[i]){

                    temp=s[j];

                    s[j]=s[i];

                    s[i]=temp;

                }

            }

        }

        System.out.println("Sorted area:");

        for(i=0;i<cnt;i++){

            System.out.printf("%.2f ",s[i]);

        }

        System.out.print("\n");

        System.out.printf("Sum of area:%.2f\n",sum);

    }

 

    static class Shape{

        double getArea(){

            return 0;

        }

 

        boolean validate(){

            return true;

        }

    }

    static class Circle extends Shape{

        double radius;

        public void getRadius(double radius){

            this.radius=radius;

        }

        @Override

        boolean validate() {

            if(radius<=0)

                return false;

            return true;

        }

        @Override

        double getArea() {

            return Math.PI*radius*radius;

        }

    }

    static class Rectangle extends Shape{

        double width;

        double length;

        @Override

        boolean validate(){

            if(width<0||length<0)

                return false;

            return true;

        }

        @Override

        double getArea(){

            return width*length;

        }

    }

    static class Triangle extends Shape{

        double side1,side2,side3;

        @Override

        boolean validate(){

            if(side1<0||side2<0||side3<0)

                return false;

            if(side1+side2<=side3||side1+side3<=side2||side2+side3<=side1)

                return false;

            return true;

        }

        @Override

        double getArea(){

            return Math.sqrt((side1+side2+side3)*(-side1+side2+side3)*(side1-side2+side3)*(side1+side2-side3))/4;

        }

    }

}

 

6.题目集六(7-6)

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

 

其中:

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

 

题目分析:本题需定义三个类,其中GetArea类只有一个方法getArea()方法求面积,Circle和Rectangle类都是GetArea的子类,需重写getArea的方法

代码:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner input = new java.util.Scanner(System.in);
        Circle circle=new Circle();
        Rectangle rectangle=new Rectangle();
        circle.radius=input.nextDouble();
        rectangle.length=input.nextDouble();
        rectangle.width=input.nextDouble();
        if (circle.radius <= 0 || rectangle.width <= 0 || rectangle.length <= 0){
             System.out.println("Wrong Format");
            System.exit(0);
        }
           
        else{
            System.out.printf("%.2f", circle.getArea());
        System.out.printf("\n%.2f", rectangle.getArea());
        }
            
    }
        static class Circle {
            double radius;

            double getArea() {
                return Math.PI * radius * radius;
            }
        }
        static class Rectangle {
            double width;
            double length;

            double getArea() {
                return width * length;
            }
        }
    }

 

正则表达式技术的分析总结:

题目集六中多次用到了正则表达式,通过Pattern和Matcher的对比来判断字符串的输入是否正确,对于输入的判断有着极大的便利。

Pattern pattern= Pattern.compile("[0-9][a-z][A-Z]");

        Matcher zz= pattern.matcher(str);

        if(zz.matches()==true)

            System.out.println(str+"属于验证码");

        else

            System.out.println(str+"不属于验证码");

 

踩坑心得:使用double类型数据时,系统会保留多位小数,一开始改成字符串时又无法进行计算,通过查找资料运用了

BigDecimal z  =   new   BigDecimal(rectangles[i].getArea());

 s[a+i] = z.setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue();

进行了两位小数的保留。

对于正则表达式的运用还不够熟练,无法熟练的将字符串很好的处理,统计Java关键词个数的时候一直无法统计正确。

 

改进建议:有些题目代码重复过多,可以简短很多,将他们归为一个类,可以对代码带来极大的便利,对正则表达式需要多加使用,达到熟练使用的程度。

 

总结:完成了三次题目集,首先对继承和多态有了很大的了解,对方法的重写,类的定义有了更深的理解,可以更好的将类处理。对字符串的处理也有了更多的了解,学会运用substring和tocharArray将字符串处理,同时对代码的逻辑有了更深的理解,写代码能力有所提高。

 

posted @ 2021-05-02 17:02  ttjjyy  阅读(88)  评论(0编辑  收藏  举报