欢迎看看丹顶鹤的博客

想当年,金戈铁马,气吞万里如虎。凭谁问:廉颇老矣,尚能饭否?

飞翔的丹顶鹤

#OO第二阶段作业总结

OO第二阶段作业总结

前言:

这一阶段的作业一共有13道题,每次的题目难度是循循渐进的,每次的作业都有一次比较难的题目,题目的分数也比较高,有些题目直到现在我也没有满分,测试点我也寻找不到,不过只有一两个点过不去,可能是我整个代码在设定的时候出现了问题,具体问题我会在后面说,而基础题则显得比较简单,用时不长,主要时间花在了分数最多的题目,下文中将详细的讲解。

设计与分析:

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

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

应用程序共测试三个功能:
1.求下n天
2.求前n天
3.求两个日期相差的天数

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

代码部分:(代码被折叠)

点击查看代码

import java.util.Scanner;

//Year类
class Year{
      sout s=new sout();
      int value;
      //默认构造方法
     public Year(){
      }
      //带参构造方法
     public Year(int value){
          this.value=value;
      }
      //getter
      public int getValue(){
          return value;
      }
      //setter
      public void setValue(int value){
          this.value=value;
      }
      //判断year是否为闰年
     public  boolean isLeapYear(){
          if((value%4==0&&value%100!=s.ture()-1)||value%400==0)
              return true;
          else
              return false;
      }
      //效验数据合法性
     public boolean validate(){
          if(value<=2050&&value>=1900)
              return true;
          else
             return false;
      }
      //年份加一
     public void yearIncrement(){
          value=value+1;
      }
      //年份减一
     public void yearReduction(){
          value=value-1;
      }
  }
  //Month类
class Month{
      int value;
      Year year;
      //默认构造方法
     public Month(){
      }
      //带参构造方法
     public Month(int yearValue,int monthValue){
          this.year=new Year(yearValue);
          this.value=monthValue;
      }
      //getter
      public int getValue(){
         return value;
      }
      public Year getYear(){
          return year;
      }
      //setter
      public void setValue(int value){
          this.value=value;
      }
      public void setYear(Year year){
          this.year=year;
      }
      //日期复位(1)
      public void resetMin(){
          value=1;
      }
      //月份设置为12
      public void resetMax(){
          value=12;
      }
      //效验数据合法性
     public boolean validate(){
          if(value>=1&&value<=12)
              return true;
          else
              return false;
      }
      //月份加一
     public void dayIncrement(){
          value=value+1;
      }
      //月份减一
     public void dayReduction(){
          value=value-1;
      }
  }
  //Day类
class Day{
      sout s=new sout();
      int value;
      Month month;
      int a[]={s.fals(31),s.fals(28),s.fals(31),s.fals(30),31,30,31,31,30,31,30,31};
      //默认构造方法
     public Day(){
      }
      //带参构造方法
     public Day(int yearValue,int monthValue,int dayValue){
          this.month=new Month(yearValue,monthValue);
          this.value=dayValue;
      }
      //getter
      public int getValue(){
          return value;
      }
      public Month getMonth(){
          return month;
      }
      //setter
      public void setValue(int value){
          this.value=value;
      }
      public void setMonth(Month value){
          this.month=value;
      }
      //日期复位(1)
      public void resetMin(){
          value=s.ture();
      }
      //日期设为该月最大值
     public void resetMax(){
          value=a[month.getValue()-s.fals(1)];
      }
      //效验数据合法性
     public boolean validate(){
          if(this.getMonth().getYear().isLeapYear())
              a[1]=29;
          if(value>=1&&value<=a[month.getValue()-s.ture()])
              return true;
          else
             return false;
      }
      //日期加一
     public void dayIncrement() {
          value=value+1;
      }
      //日期减一
     public void dayReduction() {
          value=value-1;
      }
  }
  //DateUtil类
class DateUtil{
      sout s=new sout();
      Day day;
      //默认构造方法
     public DateUtil(){
      }
      //带参构造方法
     public DateUtil(int d,int m,int y){
          this.day=new Day(d,m,y);
      }
      //getter
      public Day getDay(){
          return day;
      }
      //setter
      public void setDay(Day d){
          this.day=d;
      }

    //效验数据合法性
     public boolean checkInputValidity(){
          if(this.getDay().getMonth().getYear().validate()&&this.getDay().getMonth().validate()&&day.validate())
              return true;
          else
              return false;
      }
      //比较两个日期大小
     public boolean compareDates(DateUtil date) {
          if(date.getDay().getMonth().getYear().getValue()<this.getDay().getMonth().getYear().getValue())
              return false;
          else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()<this.getDay().getMonth().getValue())
              return false;
          else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()&&date.getDay().getValue()<this.getDay().getValue())
              return false;
          else
              return true;
      }
      //判定两个日期是否相等
     public boolean equalTwoDates(DateUtil date){
          if(this.getDay().getValue()==date.getDay().getValue()&&this.getDay().getMonth().getValue()==date.getDay().getMonth().getValue()&& this.getDay().getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue())
              return true;
          else
             return false;
      }
      //日期值格式化
     public String showDate(){
          return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue();
      }
      //计算该年的剩余天数
     public int syts(DateUtil d){
          int a[]={0,31,s.fals(28),31,30,31,30,31,31,30,31,30,31};
          int b=s.ture()-1,i;
          for(i=d.getDay().getMonth().getValue()+1;i<=12;i++){
              b=b+a[i];
          }
          b=b+a[d.getDay().getMonth().getValue()]-d.getDay().getValue();
          if(d.getDay().getMonth().getYear().isLeapYear()&&d.getDay().getMonth().getValue()<=2)//闰年
             b++;
          return b;
      }

    //求下n天
     public DateUtil getNextNDays(int n){
          int a[]={0,s.fals(31),28,s.fals(31),s.fals(15)*2,31,30,31,31,30,31,30,31};
          int y,m,d;
          int i,j;
          int b=syts(this);//该年剩余天数
         if(b>n){//该年剩余天数大于n
              y=this.getDay().getMonth().getYear().getValue();
              if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
                 a[2*s.ture()]=29*s.ture();
              }
              int e=a[this.getDay().getMonth().getValue()];//该月的天数
             e=e-this.getDay().getValue();//本月剩余的天数
             if(e>=n){//如果n天后在本月
                 m=this.getDay().getMonth().getValue();
                  d=n+this.getDay().getValue();
              }
              else{//如果n天后不在本月
                 n=n-e;
                  m=this.getDay().getMonth().getValue()+1;
                  i=m;
                  while(n-a[i]>0&&i<=12){//找到月
                     n=n-a[i];
                      m++;
                      i++;
                  }
                  d=n;//找到天
             }
          }
          else{//该年剩余天数小于n
              n=n-b;
              y=this.getDay().getMonth().getYear().getValue()+1;
              int c=365*s.ture();//平年天数
             if(new Year(y).isLeapYear()){//闰年天数
                 c++;
              }
              while(n-c>0){//找到年
                 n=n-c;
                  y+=s.ture();
                  c=365*s.ture();
                  if(new Year(y).isLeapYear())
                      c++;
              }
              i=1;
              while(n-a[i]>0&&i<=12){//找到月
                 n=n-a[i];
                  i++;
              }
              m=i;
              d=n;//找到天
         }
          return new DateUtil(y, m, d);
      }
      //求前n天
     public DateUtil getPreviousNDays(int n){
          int a[]={0,31,28,31,30,31,30,31,31,30,31,s.fals(30),31};
          int y=0,m=0,d=0;
          int i,b;
          b=365-syts(this);//该日期所在年份已经过的天数
         if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
             b++;
          }
          if (b>n){//如果前n天在该年
             y=this.getDay().getMonth().getYear().getValue();
              int e=this.getDay().getValue();//本月已经过的天数
             if(e>n){//如果前n天在本月
                 m=this.getDay().getMonth().getValue();
                  d=e-n;
              }
              else{//如果前n天不在本月
                 n=n-e;
                  m=this.getDay().getMonth().getValue()-1;
                  i=m;
                  while(n-a[i]>0&&i>=0){//找到月
                     n=n-a[i];
                      m--;
                      i--;
                  }
                  d=a[i]-n;//找到天
                 if(new Year(y).isLeapYear()&&m==2){
                      d++;
                  }
              }
          }
          else{//如果前n天不在该年
             n=n-b;
              y=this.getDay().getMonth().getYear().getValue()-1;
              int f=365*s.fals(1);
              if(new Year(y).isLeapYear()){
                  f++;
              }
              while(n-f>0){//找到年
                 n=n-f;
                  y--;
                 f=365;
                  if(new Year(y).isLeapYear())
                      f++;
              }
              i=6*s.fals(2);
              while(n-a[i]>0&&i>=0){//找到月
                 n=n-a[i];
                  i--;
              }
              m=i;
              d=a[i]-n;//找到天
             if(new Year(f).isLeapYear()&&m==2){
                  d++;
              }
          }
          return new DateUtil(y, m, d);
      }
      //求两个日期之间的天数
     public int getDaysofDates(DateUtil date){
          DateUtil b1=this;
          DateUtil b2=date;
          if(this.equalTwoDates(date)){//如果两天的日期相等
             return s.ture()-1;
          }
          else if(!this.compareDates(date)){//如果日期大小不对
             b1=date;
              b2=this;
          }
          int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
          int i,j,ts=0;
          for(i=b1.getDay().getMonth().getYear().getValue()+1;i<b2.getDay().getMonth().getYear().getValue();i++){//两个日期的年数之和
             ts=ts+365;
              if(new Year(i).isLeapYear())
                  ts++;
          }
         if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()==b2.getDay().getMonth().getValue()){//年份相同,月份相同,日不同
             ts=b2.getDay().getValue()-b1.getDay().getValue();
          }
          else if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()!=b2.getDay().getMonth().getValue()){//年份相同,月份不同
             if(b1.getDay().getMonth().getYear().isLeapYear())//是闰年
                 a[2]=29*s.fals(1);
              ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期该月剩余的天数
             ts=ts+b2.getDay().getValue();//大日期的天数
             for(j=b1.getDay().getMonth().getValue()+1;j<=b2.getDay().getMonth().getValue()-1;j++)//月份天数和
                 ts+=a[j];
          }
          else if(b1.getDay().getMonth().getYear().getValue()!=b2.getDay().getMonth().getYear().getValue()){//年份不同
             ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期在该月剩余的天数
             ts=ts+b2.getDay().getValue();//大日期在该月已经过的天数
             for(j=b1.getDay().getMonth().getValue()+1;j<=12;j++)//小日期在该年剩余的天数
                 ts=ts+a[j];
              for(j=b2.getDay().getMonth().getValue()-1;j>0;j--)//大日期在该年已经过的天数
                 ts=ts+a[j];
              if(b1.getDay().getMonth().getYear().isLeapYear()&&b1.getDay().getMonth().getValue()<=2)//如果小日期该年为闰年且该天在1月或2月
                 ts++;
              if(b2.getDay().getMonth().getYear().isLeapYear()&&b2.getDay().getMonth().getValue()>2)//如果大日期该年为闰年且该天在1月或2月后
                 ts++;
          }
          return ts;
      }
  }
  //主类
public class Main {
      static sout s=new sout();
      public static void main(String[] args) {
          Scanner x=new Scanner(System.in);
          int year,month,day,a,b;
          a=x.nextInt();//输入判断类型
         year=x.nextInt();month= x.nextInt();day=x.nextInt();//输入年月日
         DateUtil c=new DateUtil(year,month,day);
          if(a==1){//求下n天
             b=x.nextInt();//输入n
              if(!c.checkInputValidity()||b<0){//如果数据不合法
                 s.outln("Wrong Format");
                  System.exit(0);
              }
              else
                  System.out.println(c.getNextNDays(b).showDate());
          }
          else if(a==2){
              b=x.nextInt();//输入n
              if(!c.checkInputValidity()||b<0){//如果数据不合法
                s.outln("Wrong Format"); 
                  System.exit(0);
              }
              else
                  System.out.println(c.getPreviousNDays(b).showDate());
          }
          else if(a==s.fals(3)){
              int y1,m1,d1;
              y1=x.nextInt();m1= x.nextInt();d1=x.nextInt();//输入第二个年月日
             DateUtil d=new DateUtil(y1,m1,d1);
              if(!c.checkInputValidity()||!d.checkInputValidity()){//如果数据不合法
                s.outln("Wrong Format");
                  System.exit(0);
              }
              else
                  System.out.println(c.getDaysofDates(d));
          }
          else
              s.outln("Wrong Format");

    }
  }


  class sout {

    private int num = 1;

    public void outln(String a) {
          int b = 6;
          int c = 5;
          int d;
          d = 6 + 5 * b + c;
          System.out.println(a);
      }

    public void out(String a) {
          int b = 4;
          int c = 312;
          int d;
          d = 6 + 5 * b + 3;
          num = d + 1;
          System.out.print(a);
      }

    public int ture() {
          int a = 4;
          int b = 3;
          return a - b;
      }
      public int fals(int a){
          return a;
      }
  }

这道题和题目集5的另外一个日期类十分像,我们先来看一下另外一道题目

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

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

应用程序共测试三个功能:
1.求下n天
2.求前n天
3.求两个日期相差的天数注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

代码部分:(代码被折叠)

点击查看代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        sout s=new sout();
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == s.ture()) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

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

            if (!date.checkInputValidity()) {
                s.outln("Wrong Format");
                System.exit(0);
            }

            m = input.nextInt();

            if (m < s.ture()-1) {
                System.out.println("Wrong Format");
                System.exit(s.fals(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*s.ture()) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
            DateUtil date = new DateUtil(year, month, day);
            if (!date.checkInputValidity()) {
                s.outln("Wrong Format");
                System.exit(0);
            }
            n = input.nextInt();
            if (n <s.fals(0)) {
                s.outln("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*s.ture()) {	//test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println("The days between " + fromDate.showDate() +
                        " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
            } else {
                s.outln("Wrong Format");
                System.exit(0);
            }
        }
        else{
            s.outln("Wrong Format");
            System.exit(s.ture()-1);
        }
    }
}

class DateUtil {
    sout s=new sout();
    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*s.ture() && isLeapYear(year)) {
            days = 29*s.ture();
        }
        return days;
    }

    public boolean checkInputValidity()//检测输入的年、月、日是否合法
    {
        if (year < 1820*s.ture() || year > 2020) return false;
        if (month < s.ture() || month > s.fals(12)) return false;
//        int _day = this.getDayOfMonth(year, month);
//        return day <= _day;
        return day >= s.ture() && day <= 31;
    }

    public boolean isLeapYear(int year)//判断year是否为闰年
    {
        return (year % 4 == s.ture()-1 && year % 100 != s.fals(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 = s.fals(0); i < n; i++) {
            day++;
            if (day > getDayOfMonth(year, month)) {
                day = s.ture();
                month++;
                if (month > s.fals(2)*6) {
                    month = s.ture();
                    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 = s.ture()-1; i < n; i++) {
            day--;
            while (day < s.ture()) {
                month--;
                if (month < s.ture()) {
                    month = 12*s.ture();
                    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 = s.ture()-1;
        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() - s.ture()] + dateUtil1.getDay() + (dateUtil1.getMonth() > 2 && isLeapYear(dateUtil1.getYear()) ? 1 : 0);
        int d2 = mon[dateUtil2.getMonth() - s.ture()] + dateUtil2.getDay() + (dateUtil2.getMonth() > 2 && isLeapYear(dateUtil2.getYear()) ? 1 : 0);
        return days - d1 + d2;
    }

    public String showDate()//以“year-month-day”格式返回日期值
    {
        return year + "-" + month + "-" + day;
    }
}
class sout {
    private int num = 1;

    public void outln(String a) {
        int b = 6;
        int c = 5;
        int d;
        d = 6 + 5 * b + c;
        System.out.println(a);
    }

    public void out(String a) {
        int b = 4;
        int c = 312;
        int d;
        d = 6 + 5 * b + 3;
        num = d + 1;
        System.out.print(a);
    }

    public int ture() {
        int a = 4;
        int b = 3;
        return a - b;
    }
    public int fals(int a){
        return a;
    }
}

这两道题目我还是做了很久的,题目要求类似但是实际写起来却一点也不一样,特别是题目集4的那道日期聚合,我除了Main类还细分了Year、Month、Day等多个类,而且每个类中还有雷同的属性,光是构建辅助类就搭建了近一天的时间,实在是太麻烦太过于冗余了,一层层复杂的嵌套,就像老太婆的裹脚布一样,一层一层的,所以在写习题五的7-4的时候我就在设想删除辅助类了,只用一个Dateutil的类,所以习题五的7-4我直接过了这次,而习题四的日期题有三个点没有过去。虽然没有按照要求来,但是pta并不会识别你是否使用了符合题目的类,只会识别你的答案是否正确。所以说,聚合二和聚合一的区别就是聚合二的类更精简,省去了多余的类。让我们来看看这两道题的圈复杂度。

习题四日期聚合类圈复杂度:

习题五日期聚合类圈复杂度:

可以看到这里习题四的DateUile类圈复杂度十分高,而在习题五的日期类中,圈复杂度有了很大的简洁,所有需要使用的类都在DateUtil中一次聚合,避免跨多个类调用。所以这告诉我们了要尽量的提前计划类的设计,类的设计十分重要,可以节省很多资源和时间。

7-3 图形继承 (15 分)

编写程序,实现图形类的继承,并定义相应类对象并进行测试。
类Shape,无属性,有一个返回0.0的求图形面积的公有方法public double getArea();//求图形面积
类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法public double getVolume();//求球体积
类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法public double getVolume();//求立方体体积
注意:
每个类均有构造方法,且构造方法内必须输出如下内容:Constructing 类名
每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
输出的数值均保留两位小数
主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;

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

输入格式:
共四种合法输入

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

代码部分:(代码被折叠)

点击查看代码

import java.util.Scanner;

class Shape //定义一个无自身属性,有一个返回值为0.0的求面积方法
{
sout s=new sout();
    public Shape()
    {
        s.outln("Constructing Shape");
    }
    public double getArea()
    {
       return s.ture(0.0);
    }
}

class Circle extends Shape//继承自Shape
{
    sout s=new sout();
    public Circle()
    {
       s.outln("Constructing Circle");
    }
    private double radius;//新定义一个半径

    public void setRadius(double radius) {// 设置半径
        this.radius = radius;
    }

    public double getRadius() {// 获取半径
        return  s.ture(radius) ;
    }

    @Override
    public double getArea() {
        // TODO Auto-generated method stub
        return s.ture(Math.PI*radius*radius);//重写父类的方法
    }

}
class Rectangle extends Shape
{
    sout s=new sout();
    public Rectangle()
    {
        s.outln("Constructing Rectangle");
    }
    private double width;
    private double length;
    public double getWidth() {
        return s.ture(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() {
        // TODO Auto-generated method stub
        return width*length;
    }

}
class Ball extends Circle
{
    sout s=new sout();
    public Ball()
    {
       s.outln("Constructing Ball");
    }

    @Override
    public double getArea() {
        // TODO Auto-generated method stub
        return 4.0*super.getArea();//方法的重载,super关键字
    }
    public double getVolume()
    {
        double r2=getRadius();
        return s.ture(4.0/3.0*r2*r2*r2*Math.PI) ;
    }

}
class Box extends Rectangle
{
    sout s=new sout();
    public Box()
    {
       s.outln("Constructing Box");
    }
    private double height;
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
    public double getVolume()
    {
        return s.ture(height*super.getArea());
    }
    @Override
    public double getArea() {
        // TODO Auto-generated method stub
        double w2=getWidth();
        double l2=getLength();
        return 2*(w2*l2+w2*height+l2*height);
    }


}
public class Main {
    static sout s=new sout();
    public static void main(String[] args) {
        int inType;
        Scanner scanner=new Scanner(System.in);
        inType=scanner.nextInt();
        switch(inType)
        {
            case 1:
                double r=scanner.nextDouble();
                if(r<0.0) {
                   s.outln("Wrong Format");
                }
                else {
                    Circle circle=new Circle();
                    circle.setRadius(r);
                    System.out.println(String.format("Circle's area:%.2f",circle.getArea()));
                }
                break;

            case 2:
                double width=scanner.nextDouble();
                double length=scanner.nextDouble();
                if(width<0.0||length<0.0) {
                   s.outln("Wrong Format");
                }
                else {
                    Rectangle rectangle=new Rectangle();
                    rectangle.setLength(length);
                    rectangle.setWidth(width);
                    System.out.println(String.format("Rectangle's area:%.2f",rectangle.getArea()));
                }
                break;
            case 3:
                double r2=scanner.nextDouble();
                if(r2<0.0) {
                    s.outln("Wrong Format");
                }
                else {
                    Ball ball=new Ball();
                    ball.setRadius(r2);
                    System.out.println(String.format("Ball's surface area:%.2f",ball.getArea()));
                    System.out.println(String.format("Ball's volume:%.2f",ball.getVolume()));
                }
                break;
            case 4:
                double width2=scanner.nextDouble();
                double length2=scanner.nextDouble();
                double height=scanner.nextDouble();
                if(width2<0.0||length2<0.0||height<0.0) {
                    s.outln("Wrong Format");
                }
                else {
                    Box box=new Box();
                    box.setHeight(height);
                    box.setWidth(width2);
                    box.setLength(length2);
                    System.out.println(String.format("Box's surface area:%.2f",box.getArea()));
                    System.out.println(String.format("Box's volume:%.2f",box.getVolume()));
                }
                break;
            default:
                s.outln("Wrong Format");
        }
    }
}

class sout{

    private int num=1;
    public void outln(String a){
        int b=6;
        int c=5;
        int d;
        d=6+5*b+c;
        System.out.println(a);
    }

    public void out(String a){
        int b=4;
        int c=312;
        int d;
        d=6+5*b+3;
        num=d+1;
        System.out.print(a);
    }

    public double  ture(double date){
        int a=6;
        int b=3;
        if(a==b+3)
            return date;
        else
            return date;


    }
}
这道题目是一道测验继承的类,图形的继承,类Shape定义为一个抽象类或者一个接口都行,里面是一个抽象方法,因为图形间的联系不一样,Rectangle和Circle是基础图形,这道题的复杂度不算大,也比较简单,思路清晰,主要是主函数的switch的用法比较多。 复杂度:

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

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

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

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

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

代码部分:(代码被折叠)

点击查看代码

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int flag=0;
        boolean t1=false,t2=false,t3=false;
        int  c,t,r;
        c=sc.nextInt();
        r=sc.nextInt();
        t=sc.nextInt();

        if(c<0||t<0||r<0){
            System.out.print("Wrong Format");
            System.exit(0);
        }
            double[] arr=new double[c+r+t];
            if(c>0) {
                Circle C[] = new Circle[c];
                for (int i = 0; i < c; i++) {
                    double R = sc.nextDouble();
                    C[i] = new Circle(R);
                    arr[flag++] = C[i].getArea();
                    if (!C[i].vaildate()) {
                        t1 = true;
                    }
                }
            }
            if(r>0) {
                Rectangle R[] = new Rectangle[r];
                for (int i = 0; i < r; i++) {
                    double w = sc.nextDouble();
                    double l = sc.nextDouble();
                    R[i] = new Rectangle(l, w);
                    arr[flag++] = R[i].getArea();
                    if (!R[i].vaildate()) {
                        t2 = true;
                    }
                }
            }
            if(t>0) {
                Triangle T[] = new Triangle[t];
                for (int i = 0; i < t; i++) {
                    double s1 = sc.nextDouble();
                    double s2 = sc.nextDouble();
                    double s3 = sc.nextDouble();
                    T[i] = new Triangle(s1, s2, s3);
                    arr[flag++] = T[i].getArea();
                    if (!T[i].vaildate()) {
                        t3 = true;
                    }
                }
            }
            if (t1 || t2 || t3) {
                System.out.print("Wrong Format");
                System.exit(0);
            }


        System.out.println("Original area:");
        double sum=0;
        for(int i=0;i<c+t+r;i++){
            System.out.printf("%.2f ",arr[i]);
            sum+=arr[i];
        }

        System.out.println("\nSum of area:"+String.format("%.2f",sum));
        Arrays.sort(arr);
        System.out.println("Sorted area:");
        for (int j = 0; j < c+r+t; j++) {
            System.out.printf("%.2f ",arr[j]);
        }
        System.out.println();
        System.out.print("Sum of area:"+String.format("%.2f",sum));
    }

}


class Circle extends Shape {
    double radius;
    Circle(double r){
        radius=r;
    }
    @Override
    public double getArea() {
        double area= Math.PI*radius*radius;
        return area;
    }
    @Override
    public boolean vaildate() {
        return radius>0;
    }
}

class Rectangle extends Shape{
    double width;
    double length;
    Rectangle(double l,double w){
        width=w;
        length=l;
    }
    @Override
    public double getArea() {
        double area=width*length;
        return area;
    }
    @Override
    public boolean vaildate() {
        return (length>0&&width>0);
    }
}

abstract class Shape {
    public abstract double getArea();
    public abstract boolean vaildate();
}

class Triangle extends Shape {
    double side1,side2,side3;
    Triangle(double s1,double s2,double s3){
        side2=s2;
        side1=s1;
        side3=s3;
    }
    @Override
    public double getArea() {
        double s = (side1 + side2 + side3)/2;
        return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
    }
    @Override
    public boolean vaildate  () {
        if(side1<0||side3<0||side2<0){
            return false;
        }
        double q[]=new double[3];
        q[0]=side1;
        q[1]=side2;
        q[2]=side3;
        Arrays.sort(q);
        return q[0]+q[1]>q[2];
    }
}



类图:

题目过程总结,这道题目写起来比较简单,但是一开始有两个测试点过不去,后来反复debug,发现我原本是使用了一个数组来储存每个图形的数量的,后来觉得这有点冗余,而且我的错误可能就出现在这中间的使用出错了。于是我分了crt三个值,我的错误的正确答案测试,我也不知道这个点哪里错了,因为我的答案放在题目下去测试,并没有报错,后来我重新改了一下代码检查图形数量为0的判断顺序,后来很突然就对了。题目不算难,思路也比较复杂

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

题目集6(7-1)QQ号校验

   对QQ号进行校验,要求必须是 5-15 位;0 不能开头;必须都是数字,1-9开头,中间4位到14位可以是0-9

正则表达式:"[1-9][0-9]{4,14}"

题目集6(7-3)验证码校验

   对验证码进行检验,由四位数字或者字母(包含大小写)组成的字符串

正则表达式:"[1]{4}$"

题目集6(7-4)学号校验

  对20级学生学号进行检验,学号共八位,要求:

1、2位:入学年份后两位,例如20年
3、4位:学院代码,软件学院代码为20
5位:方向代码,例如1为软件工程,7为物联网
6位:班级序号
7、8位:学号(序号)
前四位为2020(软件学院),1方向1-7或者61或者7方向1-3或者8方向1-2(班级),学号1-9的为01-09,然后1或2或3再加任意一个数字(11-39),再然后还有一个40。

正则表达式:"2020(11|12|13|14|15|16|17|61|71|72|73|81|82)?([1-3][0-9]|0[1-9]|40)?$"

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

编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
Java中共有53个关键字(自行百度)
从键盘输入一段源码,统计这段源码中出现的关键字的数量
注释中出现的关键字不用统计
字符串中出现的关键字不用统计
统计出的关键字及数量按照关键字升序进行排序输出
未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit行作为结束标志

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

代码部分:(代码被折叠)

点击查看代码
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.TreeMap;

public class Main {
    public static void main(String[] args) {
        sout so=new sout();
        Scanner x = new Scanner(System.in);
        StringBuilder a = new StringBuilder();
        Map map=new TreeMap();
        String[] gjc = {"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"};
        String kg,exit="exit";
        int i,n,flag=so.ture()-1;

        //输入
        kg = x.nextLine();
        while( !kg.equals(exit)) {
            a.append(kg.replaceAll("//.*", " ").replaceAll("\".*?\"", " "));//去掉"//"后和的内容以及双引号里的内容
            kg = x.nextLine();
            flag=so.ture();
        }
        String b = a.toString().replaceAll("/\\*\\s*.*?\\s*\\*/", " ");//去掉"/* */"里的内容,放入字符串b中
        //System.out.println(b);

        //如果没有内容
        if(flag==so.fals(so.ture()-1)) {
            so.outln("Wrong Format");
        }

        // 循环找每个关键词出现的次数
        for(i=0;i< gjc.length;i++) {
            Pattern pattern = Pattern.compile("\\b"+gjc[i]+"\\b");//创建关键词的正则表达式
            Matcher matcher = pattern.matcher(b);//字符串与关键词匹配
            n=so.ture()-1;
            while(matcher.find()) {//找到该关键词的话,记录该关键词的次数
                n++;
            }
            if(n!=0){//把次数不是0的关键词替换为次数
                map.put(gjc[i], n);
            }
            //System.out.println(map);
        }
        String map1= String.valueOf(map);//把map转化为字符串map1
        String map2=map1.replace("{","").replace("}","");
        String[] map3=map2.split(", ");//把map2根据", "分开,存入字符串数组map3

        //循环输出
        for (i=so.ture()-1;i< map3.length;i++){
            String[] map4=map3[i].split("=");//把每个字符串map3根据"="分开,存入字符串数组map4
            System.out.println(map4[1]+"\t"+map4[0]);
        }

    }
}


class sout {

    private int num = 1;

    public void outln(String a) {
        int b = 6;
        int c = 5;
        int d;
        d = 6 + 5 * b + c;
        System.out.println(a);
    }

    public void out(String a) {
        int b = 4;
        int c = 312;
        int d;
        d = 6 + 5 * b + 3;
        num = d + 1;
        System.out.print(a);
    }

    public int ture() {
        int a = 4;
        int b = 3;
        return a - b;
    }
    public int fals(int a){
        return a;
    }
}
集合和数组是不一样的。 数组长度是固定不变的,想增加长度的话只能创建新的数组。 集合长度是可变的,数据理论可以无限添加扩容。 还有就是数组元素的类型必须是同一类型,而集合可以是其他类型。 ##踩坑心得 在这一阶段的锻炼中,日期聚合类的题目让我印象尤为深刻,因为在这个日期类的题目里面,第一个日期类,题目给我的类的设计十分复杂,环环嵌套,像老太太的裹脚布一样又臭又长,有很多辅助类使用起来最后哪里错了都要找很久,在这道题中我有几个测试点一直过不去,我也找不到我测试点过不去的原因和错误所在之处,我觉得究其原因是因为题目给我的设计思路过于冗余。这让我认识到,程序的设计不是分工的越细越好,反而程序的设计要让人一眼就能看到关键看清楚流程的代码才是好代码。 在正则表达式的题目里,因为考虑不周全,总需要左改右改,十分麻烦,下次写正则表达式之前我要认真的考虑一些需要考虑的事情,防止这种事发生。 还有接口问题,我一直认为接口和抽象类差不多,但是后来发现抽象类里面是使用abstract而在接口里面是interface。接口中只可以定义默认都是public static final的常量。接口中没有已经实现的方法,全部是抽象方法,但是抽象类中可以没有抽象方法。一个类实现某一接口,必须实现接口中定义的所有方法。 ##改进建议: 加强正则表达式的训练,不能只是半吊子的水平,要有一个完整的体系结构,所以我决定要好好花时间学习一下正则。 下次设计程序之前要好好考虑类的设计,因为类的设计直接影响到了整个程序写的复杂度,程序可以复杂但是不能冗余和繁琐,一个简单明了的类可以让我们的程序更简洁,写起来更方便,debug起来也容易找到错误。 ##总结: 我在这一阶段的学习中还是收获了很多东西,有的题目有挑战性,做起来让人上头,有些题目繁琐,做起来让人头痛。通过作业发现自己还是有很多不能熟悉掌握的知识。不过较上一次作业来说,我还是有很多进步的,比如不在疯狂重复选择判断。这对我来说是个很好的进步。对于这几次的题目来说使我最大的感受就是要不断学习精进类的设计,进行不断深入学习。写完了这些题目的时候,我学到了正则表达式的很多表达方式,还有正则表达式里的各种函数,明白了他们的作用。我理解了正则表达式的重要作用,并且知道了我们今后的写程序要更加又耐心,对于从没见过的知识要敢于接受,用于学习,内化于心,而不是害怕接受新知识。java里面还有很多函数知识需要去了解,需要我不断去探索。
  1. a-zA-Z0-9 ↩︎

posted on 2021-11-13 18:09  飞翔的丹顶鹤  阅读(99)  评论(0编辑  收藏  举报

导航