最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

关于PTA第二次大作业的总结-热点

来源:博客园

一.前言


【资料图】

这一次的作业,总体来说是有一定难度的,主要考察了类与对象的关系,java封装的技术特性,字符串的使用和正则表达式的使用等,还有java类的设计原则,题量比之前的作业减少了,但是难度在慢慢上升。特别是习题六,代码的数量上来了,关于类的设计就要谨慎。

二.设计与分析

7-1 菜单计价程序-3分数30作者蔡轲单位南昌航空大学

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu {

Dish\[\] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

点菜记录类:保存订单上的一道菜品记录

Record {

int orderNum;//序号\\

Dish d;//菜品\\

int portion;//份额(1/2/3代表小/中/大份)\\

int getPrice()//计价,计算本条记录的价格\\

}

订单类:保存用户点的所有菜的信息。

Order {

Record\[\] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

### 输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

### 输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+“:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入样例:

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

麻婆豆腐 12油淋生菜 9table 1 2023/3/22 12/2/31 麻婆豆腐 2 22 油淋生菜 1 3end

输出样例:

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

table 1: 1 麻婆豆腐 362 油淋生菜 27table 1: 38

输入样例1:

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

麻婆豆腐 12油淋生菜 9table 1 2023/3/22 17/0/01 麻婆豆腐 2 22 油淋生菜 1 31 deleteend

输出样例1:

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

table 1: 1 麻婆豆腐 362 油淋生菜 27table 1: 22

输入样例2:

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

麻婆豆腐 12油淋生菜 9table 1 2023/3/22 16/59/591 麻婆豆腐 2 22 油淋生菜 1 31 deleteend

输出样例2:

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

table 1: 1 麻婆豆腐 362 油淋生菜 27table 1 out of opening hours

输入样例3:

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

麻婆豆腐 12油淋生菜 9table 1 2022/12/5 15/03/021 麻婆豆腐 2 22 油淋生菜 1 33 麻辣鸡丝 1 25 delete7 deletetable 2 2022/12/3 15/03/021 麻婆豆腐 2 22 油淋生菜 1 33 麻辣鸡丝 1 27 deleteend

输出样例3:

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

table 1: 1 麻婆豆腐 362 油淋生菜 27麻辣鸡丝 does not existdelete error;delete error;table 2: 1 麻婆豆腐 362 油淋生菜 27麻辣鸡丝 does not existdelete error;table 1 out of opening hourstable 2: 63

输入样例4:

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

麻婆豆腐 12油淋生菜 9table 1 2022/12/3 19/5/121 麻婆豆腐 2 22 油淋生菜 1 33 麻辣鸡丝 1 2table 2 2022/12/3 15/03/021 麻婆豆腐 2 22 油淋生菜 1 33 麻辣鸡丝 1 21 4 麻婆豆腐 1 17 deleteend

输出样例4:

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

table 1: 1 麻婆豆腐 362 油淋生菜 27麻辣鸡丝 does not existtable 2: 1 麻婆豆腐 362 油淋生菜 27麻辣鸡丝 does not exist4 table 2 pay for table 1 12delete error;table 1: 63table 2: 75刚开始看这道题目的时候,我是没什么头绪的,我是最后才来做这道题的。源码如下:
1 import java.util.*; 2  3 public class Main{    4     public static void main (String[] args){ 5 //         Scanner input = new Scanner(System.in); 6 //         int i = 0; 7 //         Dish dish[] = new Dish(); 8 //        do{ 9 //            dish[i].name = input.next();10 //            dish[i].unit_price = input.nextInt();11 //        }12         13     }14 }15 class Dish{ 16     String name;//菜品名称17     int unit_price;//单价18    19     Dish(){20         21     }22     Dish(String name,int unit_price){23         this.name = name;24         this.unit_price = unit_price;25     }26     27     public int getPrice(int portion){//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)28         if(portion == 1)29             return unit_price*1;30         if(portion == 2)31             return unit_price*1.5;32         if(portion == 3)33             return unit_price*2;34     }35 }36 class Menu{37     Dish[] dishs;//菜品数组,保存所有菜品信息38     39     public  Dish searchDish(String dishName){//根据菜名在菜谱中查找菜品信息,返回Dish对象。40         for(int i = 0;i < dishs.length;i++){41             if(dishs[i].equals(dishName)){42                 return dishs[i];43             }44         }45     }46     public Dish addDish(String dishName,int unit_price){//添加一道菜品信息47        // dishs[dishs.length] = new Dish(dishName,unit_price);48     }49     50 }51 class Record{52     int orderNum;//序号53     Dish d;//菜品54     int portion;//份额(1/2/3代表小/中/大份)55     56     Record(){57         58     }59     //Record(int orderNum,String dishName,int portion,int portion60       //  this.orderNUm = orderNum;61 //         d.dishName = dishName;62 // //         d.portion63     //}64 65     66     public int getPrice(){//计价,计算本条记录的价格\\67        int result ;68        if(portion == 1){69            result = d.unit_price*1;70        }71        if(portion == 2)72            result =(int) ( d.unit_price*1.5);73        if(portion == 3)74            result = d.unit_price*2;75     }76 }77 // class Order{78 //     Record[] records;//保存订单上每一道的记录79     80 //     int getTotalPrice(){//计算订单的总价81 //         int sum = 0;82 //         for(i = 0; i < records.length;i++){83 //             sum += records[i].getPrice();84 //         }85 //     }86 //     Record addARecord(int orderNum,String dishName,int portion,int num){//添加一条菜品信息87 //         this.orderNum = orderNum;88 //         d.dishName = dishName;89 //         d.portion = portion;90 //         this.num = num;91 //     }92 //     delARecordByOrderNum(int orderNum){//根据序号删除一条记录93 //         Record[num] = 94 //     }95 //     findRecordByNUm(int orderNum){////根据序号查找一条记录96        97 //     }98 // }
可以看到笔者的代码还不完整,还有一些功能没有完善,仅仅只有一些框架,按照题目意思:menu类里有dish对象,order里有record对象。这些类之间为依赖关系,测试如下:可以看到只得了一分。

后面就不知道怎么做了,总在纠结要不要用二维数组来存储输入的信息,然后后面的具体方法的实现就没怎么写,最够也没写出这道题。

生成的类图如下:

7-5 日期问题面向对象设计(聚合一)分数50作者段喜龙单位南昌航空大学

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

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

  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

源码如下:
1 import java.util.Scanner;  2   3 public class Main {  4     public static void main(String[] args) {  5         Scanner input = new Scanner(System.in);  6         String str = input.nextLine();  7         String[] str1 = str.split(" ");  8         switch(str1[0]){  9             case "1":{ 10                 int y = Integer.valueOf(str1[1]); 11                 int m = Integer.valueOf(str1[2]); 12                 int d = Integer.valueOf(str1[3]); 13                 int n = Integer.valueOf(str1[4]); 14                 DateUtil date = new DateUtil(d,m,y); 15                 if(date.checkInputValidity()) 16                     System.out.println(date.getNextNDays(n).showDate()); 17                 else 18                     System.out.println("Wrong Format"); 19             }break; 20             case "2":{ 21                 int y = Integer.valueOf(str1[1]); 22                 int m = Integer.valueOf(str1[2]); 23                 int d = Integer.valueOf(str1[3]); 24                 int n = Integer.valueOf(str1[4]); 25                 DateUtil date = new DateUtil(d,m,y); 26                 if(date.checkInputValidity()) 27                     System.out.println(date.getPreviousNDays(n).showDate()); 28                 else 29                     System.out.println("Wrong Format"); 30             }break; 31             case "3":{ 32                 int y1 = Integer.valueOf(str1[1]); 33                 int m1 = Integer.valueOf(str1[2]); 34                 int d1 = Integer.valueOf(str1[3]); 35                 int y2 = Integer.valueOf(str1[4]); 36                 int m2 = Integer.valueOf(str1[5]); 37                 int d2 = Integer.valueOf(str1[6]); 38                 DateUtil date1 = new DateUtil(d1,m1,y1); 39                 DateUtil date2 = new DateUtil(d2,m2,y2); 40                 int n = date1.getDaysofDates(date2); 41                 System.out.println(n); 42                  43             }break; 44             default:{ 45                  46             } 47         }//switch 48     } 49 } 50 class DateUtil{ 51     private Day day = new Day(); 52      53      54     DateUtil(){ 55          56     } 57     DateUtil(int d, int m, int y){ 58         day.setValue(d); 59         day.getMonth().setValue(m); 60         day.getMonth().getYear().setValue(y); 61     } 62      63      64     public Day getDay(){ 65         return day; 66     } 67     public void setDay(Day d){ 68         this.day = d; 69     } 70     public boolean checkInputValidity(){ 71            72         if(day.getMonth().getYear().validate()){ 73             if(day.getMonth().validate()){ 74                 if(day.validate()) 75                     return  true; 76                 else 77                     return false; 78                            79             } 80             else 81                 return false; 82         } 83         else 84             return false; 85          86     } 87     public boolean compareDates(DateUtil date){ 88         if(day.getMonth().getYear().getValue() > date.getDay().getMonth().getYear().getValue()) { 89             return true; 90         } 91         else if(day.getMonth().getYear().getValue() < date.getDay().getMonth().getYear().getValue()) { 92             return false; 93         } 94         else { 95             if(day.getMonth().getValue() > date.getDay().getMonth().getValue()) { 96                 return true; 97             } 98             else if(day.getMonth().getValue() < date.getDay().getMonth().getValue()) { 99                 return false;100             }101             else {102                 if(day.getValue() > date.getDay().getValue())103                     return true;104                 else105                     return false;106                     107             }108         }109     } 110     public boolean equalTwoDates(DateUtil date){111         if(day.getValue() == date.getDay().getValue() && day.getMonth().getValue() == date.getDay().getMonth().getValue() && day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue())112             return true;113         else114             return false;115     }116     public String showDate(){117         String str = "" + day.getMonth().getYear().getValue() + "-" + day.getMonth().getValue() + "-" + day.getValue();118         return str;119     }120     public DateUtil getNextNDays(int n){121         for( ; n > 0 ; n--){122             if(day.getMonth().getValue() != 12){123                 if(day.getMonth().getValue() == 2){124                     if(day.getMonth().getYear().isLeapYear()){125                         if(day.getValue() != 29)126                             day.dayIncrement();127                         else{128                             day.resetMin();129                             day.getMonth().monthIncrement();130                         131                         }132                     }133                     else{//不是闰年134                         if(day.getValue() != 28)135                             day.dayIncrement();136                         else{137                             day.resetMin();138                             day.getMonth().monthIncrement();139                         }140                     }141                 }//2月142                 else{//不是二月143                     if(day.getMonth().getValue() == 1 || day.getMonth().getValue() == 3 || day.getMonth().getValue() == 5 || day.getMonth().getValue() == 7 || day.getMonth().getValue() == 8 || day.getMonth().getValue() == 10){144                         if(day.getValue() != 31)145                             day.dayIncrement();146                         else{147                             day.resetMin();148                             day.getMonth().monthIncrement();149                         }150                             151                     }152                     else {153                         if(day.getValue() != 30)154                             day.dayIncrement();155                         else{156                             day.resetMin();157                             day.getMonth().monthIncrement();158                 159                         }160                     }161       162                 }163             }164             else{ //是12月165                 if(day.getValue() != 31)166                     day.dayIncrement();167                 else{168                     day.resetMin();169                     day.getMonth().resetMin();170                     day.getMonth().getYear().yearIncrement();171                 }172             }173                174         }//n175         DateUtil newDate = new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());176         return newDate;177     }178     public DateUtil getPreviousNDays(int n){179          for( ; n > 0 ; n--){180              if(day.getMonth().getValue() == 1){181                  if(day.getValue() == 1){182                      day.resetMax();183                      day.getMonth().resetMax();184                      day.getMonth().getYear().yearReduction();185                  }186                  else{187                      day.dayReduction();188                  }189              } 190              else {191                      if(day.getValue() == 1){192                          day.getMonth().monthReduction();193                          day.resetMax();194                      }195                      else196                          day.dayReduction();197              }    198          }199 200         DateUtil newDate = new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());201         return newDate;202         203     }204     public int getDaysofDates(DateUtil date){205         int n = 0;int flag = 0;206         if(compareDates(date) ){207             flag = 1;208         }209         else210             flag = 0;211         if(flag == 0){212             for( ; this.equalTwoDates(date) == false ; n++){213               if(day.getMonth().getValue() != 12){214                 if(day.getMonth().getValue() == 2){215                     if(day.getMonth().getYear().isLeapYear()){216                         if(day.getValue() != 29)217                             day.dayIncrement();218                         else{219                             day.resetMin();220                             day.getMonth().monthIncrement();221                         }222                     }223                     else{//不是闰年224                         if(day.getValue() != 28)225                             day.dayIncrement();226                         else{227                             day.resetMin();228                             day.getMonth().monthIncrement();229                         }230                     }231                 }//2月232                 else{//不是二月233                     if(day.getMonth().getValue() == 1 || day.getMonth().getValue() == 3 || day.getMonth().getValue() == 5 || day.getMonth().getValue() == 7 || day.getMonth().getValue() == 8 || day.getMonth().getValue() == 10){234                         if(day.getValue() != 31)235                             day.dayIncrement();236                         else{237                             day.resetMin();238                             day.getMonth().monthIncrement();239                         }240                             241                     }242                     else {243                         if(day.getValue() != 30)244                             day.dayIncrement();245                         else{246                             day.resetMin();247                             day.getMonth().monthIncrement();248                         }249                     }250       251                 }252             }253             else{ //是12月254                 if(day.getValue() != 31)255                     day.dayIncrement();256                 else{257                     day.resetMin();258                     day.getMonth().resetMin();259                     day.getMonth().getYear().yearIncrement();260                 }261             }262          }263         }264         else {265             for( ; this.equalTwoDates(date) == false ; n++ ){266                 if(day.getMonth().getValue() == 1){267                  if(day.getValue() == 1){268                      day.resetMax();269                      day.getMonth().resetMax();270                      day.getMonth().getYear().yearReduction();271                  }272                  else{273                      day.dayReduction();274                  }275              } 276              else {277                      if(day.getValue() == 1){278                          day.getMonth().monthReduction();279                          day.resetMax();280                      }281                      else282                          day.dayReduction();283              }    284             }285         }286              287         return n;288     }289 }290 291 class Day{292     private int value;293     private Month month = new Month();294     private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31};295     296     Day(){297         298     }299     Day(int yearValue, int monthValue, int dayValue){300         value = dayValue;301         month.setValue(monthValue);302         month.getYear().setValue(dayValue);303     }304     305     public int getValue(){306         return value;307     }308     public void setValue(int value){309         this.value = value;310     }311     public Month getMonth(){312         return month;313     }314     public void setMonth(Month value){315         this.month = value;316     }317     public void resetMin(){318         value = 1;319     }320     public void resetMax(){321         if(month.getYear().isLeapYear()){322             if(month.getValue() == 2)323                 value = 29;324             else325                 value = mon_maxnum[month.getValue()-1];326         }327         else{328             if(month.getValue() == 2)329                 value = 28;330             else331                 value = mon_maxnum[month.getValue()-1];332         }333        334     }335     public boolean validate(){336         if(month.getValue() == 2){337             if(month.getYear().isLeapYear()){338                 if(value >= 1 && value <= 29)339                     return true;340                 else341                     return false;342             }343             else{344                 if(value >= 1 && value <= 28)345                     return true;346                 else 347                     return false;348             }349                 350         }351         else{352             if(value >= 1 && value <= mon_maxnum[month.getValue()-1])353                 return true;354             else355                 return false;356         }357          358     }359     public void dayIncrement(){360         value++;361     }362     public void dayReduction(){363         value--;364     }365 }366 367 class Month{368     private int value;369     private Year year = new Year();370     371     Month(){372         373     }374     Month(int yearValue, int monthValue){375         value = monthValue;376         year.setValue(yearValue);377     }378     379     public int getValue(){380         return value;381     }382     public void setValue(int value){383          this.value = value; 384     }385     public Year getYear(){386         return year;387     }388     public void setYear(Year year){389         this.year = year;390     }391     public void resetMin(){392         value = 1;393     }394     public void resetMax(){395         value = 12;396     }397     public boolean validate(){398         if(value >= 1 && value <= 12)399             return true;400         else401             return false;402     }403     public void monthIncrement(){404         value++;405     }406     public void monthReduction(){407         value--;408     }409 }410 411 class Year{412     private int value;413     414     Year(){415         416     }417     Year(int value){418         this.value = value;419     }420     421     public int getValue(){422         return value;423     }424     public void setValue(int value){425         this.value = value;426     }427     public boolean isLeapYear(){428         if((value % 4 == 0 && value % 100 != 0) || value % 400 == 0)429             return true;430         else431             return false;432     }433     public boolean validate(){434         if(value >= 1900 && value <= 2050)435             return true;436         else437             return false;438     }439     public void yearIncrement(){440         value++;441     }442     public void yearReduction(){443         value--;444     }445 }446         447         
View Code

运行结果如下:

这题的话,在DateUtil类中有Day类对象,Day类中有Month对象,在Month类中有Year对象,这些类之间的关系都是聚合关系;这个题目更好解释了类与类之间的关系,如下图:

day对象调用month对象,month对象再调用year对象,year对象调用setValue方法,从而实现改变年份。我写的时候对年份的判定老是出现错误,其实参照习题四的题目就行了。在下写求两个日期的之间的天数,我用的是循环的方法,若前面的日期更小,则调用下N天的函数,循环N次;若前面的日期较大,则调用求上N天的方法,循环N次,这样就得到了两个日期之间的天数。相应的代码如下:

1 public int getDaysofDates(DateUtil date){ 2         int n = 0;int flag = 0; 3         if(compareDates(date) ){ 4             flag = 1; 5         } 6         else 7             flag = 0; 8         if(flag == 0){ 9             for( ; this.equalTwoDates(date) == false ; n++){10               if(day.getMonth().getValue() != 12){11                 if(day.getMonth().getValue() == 2){12                     if(day.getMonth().getYear().isLeapYear()){13                         if(day.getValue() != 29)14                             day.dayIncrement();15                         else{16                             day.resetMin();17                             day.getMonth().monthIncrement();18                         }19                     }20                     else{//不是闰年21                         if(day.getValue() != 28)22                             day.dayIncrement();23                         else{24                             day.resetMin();25                             day.getMonth().monthIncrement();26                         }27                     }28                 }//2月29                 else{//不是二月30                     if(day.getMonth().getValue() == 1 || day.getMonth().getValue() == 3 || day.getMonth().getValue() == 5 || day.getMonth().getValue() == 7 || day.getMonth().getValue() == 8 || day.getMonth().getValue() == 10){31                         if(day.getValue() != 31)32                             day.dayIncrement();33                         else{34                             day.resetMin();35                             day.getMonth().monthIncrement();36                         }37                             38                     }39                     else {40                         if(day.getValue() != 30)41                             day.dayIncrement();42                         else{43                             day.resetMin();44                             day.getMonth().monthIncrement();45                         }46                     }47       48                 }49             }50             else{ //是12月51                 if(day.getValue() != 31)52                     day.dayIncrement();53                 else{54                     day.resetMin();55                     day.getMonth().resetMin();56                     day.getMonth().getYear().yearIncrement();57                 }58             }59          }60         }61         else {62             for( ; this.equalTwoDates(date) == false ; n++ ){63                 if(day.getMonth().getValue() == 1){64                  if(day.getValue() == 1){65                      day.resetMax();66                      day.getMonth().resetMax();67                      day.getMonth().getYear().yearReduction();68                  }69                  else{70                      day.dayReduction();71                  }72              } 73              else {74                      if(day.getValue() == 1){75                          day.getMonth().monthReduction();76                          day.resetMax();77                      }78                      else79                          day.dayReduction();80              }    81             }82         }83              84         return n;85     }

这个题目将一个功能交给一个方法实现,体现了java中的单一职责原则,代码实现过程也更好写。

生成的类图如下:

生成的类图,由于都在一个java文件中,main与其他类都有依赖关系,不完全符合题目的要求。

7-6 日期问题面向对象设计(聚合二)分数34作者段喜龙单位南昌航空大学

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

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

  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

代码如下:
1 import java.util.Scanner;  2   3 public class Main {  4     public static void main(String[] args) {  5         Scanner input = new Scanner(System.in);  6         String str = input.nextLine();  7         String[] str1 = str.split(" ");  8         switch(str1[0]){  9             case "1":{ 10                 int y = Integer.valueOf(str1[1]); 11                 int m = Integer.valueOf(str1[2]); 12                 int d = Integer.valueOf(str1[3]); 13                 int n = Integer.valueOf(str1[4]); 14                  15                 DateUtil date = new DateUtil(d,m,y); 16                 if(date.checkInputValidity()) 17                     System.out.println(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + n + " days is:" + date.getNextNDays(n).showDate()); 18                 else 19                     System.out.println("Wrong Format"); 20             }break; 21             case "2":{ 22                 int y = Integer.valueOf(str1[1]); 23                 int m = Integer.valueOf(str1[2]); 24                 int d = Integer.valueOf(str1[3]); 25                 int n = Integer.valueOf(str1[4]); 26                 DateUtil date = new DateUtil(d,m,y); 27                 if(date.checkInputValidity()) 28                     System.out.println(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " previous " + n + " days is:" + date.getPreviousNDays(n).showDate()); 29                 else 30                     System.out.println("Wrong Format"); 31             }break; 32             case "3":{ 33                 int y1 = Integer.valueOf(str1[1]); 34                 int m1 = Integer.valueOf(str1[2]); 35                 int d1 = Integer.valueOf(str1[3]); 36                 int y2 = Integer.valueOf(str1[4]); 37                 int m2 = Integer.valueOf(str1[5]); 38                 int d2 = Integer.valueOf(str1[6]); 39                 DateUtil date1 = new DateUtil(d1,m1,y1); 40                 DateUtil date2 = new DateUtil(d2,m2,y2); 41                 System.out.print("The days between " + date1.getYear().getValue() + "-" + date1.getMonth().getValue() + "-" + date1.getDay().getValue() + " and " + date2.getYear().getValue() + "-" + date2.getMonth().getValue() + "-" + date2.getDay().getValue() + " are:"); 42                 int n = date1.getDaysofDates(date2); 43                 System.out.print(n); 44             }break; 45             default:{ 46                 System.out.println("Wrong Format"); 47             } 48         }//switch 49     } 50 } 51 class DateUtil{ 52     private Year year = new Year(); 53     private Month month = new Month(); 54     private Day day = new Day(); 55     private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31}; 56      57      58      59     DateUtil(){ 60          61     } 62     DateUtil(int d, int m, int y){ 63         year.setValue(y); 64         month.setValue(m); 65         day.setValue(d); 66     } 67     public  Year getYear(){ 68         return year; 69     } 70     public void setYear(Year year){ 71         this.year = year; 72     } 73     public Month getMonth(){ 74         return month; 75     } 76     public void setMonth(Month month){ 77         this.month = month; 78     } 79     public Day getDay(){ 80         return day; 81     } 82     public void setDay(Day day){ 83         this.day = day; 84     } 85     public void setDayMin(){ 86         day.setValue(1); 87     } 88     public void setDayMax(){ 89        if(year.isLeapYear()){ 90             if(month.getValue() == 2) 91                 day.setValue(29);  92             else 93                 day.setValue(mon_maxnum[month.getValue()-1]);  94         } 95         else{ 96             if(month.getValue() == 2) 97                 day.setValue(28); 98             else 99                 day.setValue(mon_maxnum[month.getValue()-1]) ;100         }101        102     }103     public boolean checkInputValidity(){104         if(year.validate()){105             if(month.validate()){106                   if(month.getValue() == 2){107                 if(year.isLeapYear()){108                     if(day.getValue() >= 1 && day.getValue() <= 29)109                         return true;110                     else111                         return false;112                 }113                 else{114                     if(day.getValue() >= 1 && day.getValue() <= 28)115                         return true;116                     else 117                         return false;118                 }119                     120             }121             else{122                 if(day.getValue() >= 1 && day.getValue() <= mon_maxnum[month.getValue()-1])123                     return true;124                 else125                     return false;126               }127             }128             else129                 return false;130         }131         else132             return false;133 134     }135     public DateUtil getNextNDays(int n){136          for( ; n > 0 ; n--){137             if(month.getValue() != 12) {//不是12月138                 if(month.getValue() == 2){//二月139                     if(year.isLeapYear()){140                         if(day.getValue() != 29)141                             day.dayIncrement();142                         else{143                             setDayMin();144                             month.monthIncrement();145                         146                         }147                     }148                     else{//不是闰年149                         if(day.getValue() != 28)150                             day.dayIncrement();151                         else{152                             setDayMin();153                             month.monthIncrement();154                         }155                     }156                 }//2月157                 else{//不是二月158                     if(month.getValue() == 1 || month.getValue() == 3 || month.getValue() == 5 || month.getValue() == 7 || month.getValue() == 8 || month.getValue() == 10){159                         if(day.getValue() != 31)160                             day.dayIncrement();161                         else{162                             this.setDayMin();163                             month.monthIncrement();164                         }165                             166                     }167                     else {168                         if(day.getValue() != 30)169                             day.dayIncrement();170                         else{171                             this.setDayMin();172                             month.monthIncrement();173                 174                         }175                     }176       177                 }178             }179             else{ //是12月180                 if(day.getValue() != 31)181                     day.dayIncrement();182                 else{183                     this.setDayMin();184                     month.resetMin();185                     year.yearIncrement();186                 }187             }188                189         }//n190         DateUtil newDate = new DateUtil(day.getValue(),month.getValue(),year.getValue());191         return newDate;192     }193     public DateUtil getPreviousNDays(int n){194         for( ; n > 0 ; n--){195              if(month.getValue() == 1){196                  if(day.getValue() == 1){197                      this.setDayMax();198                      month.resetMax();199                      year.yearReduction();200                  }201                  else{202                      day.dayReduction();203                  }204              } 205              else {206                      if(day.getValue() == 1){207                          month.monthReduction();208                          this.setDayMax();209                      }210                      else211                          day.dayReduction();212              }    213          }214          DateUtil newDate = new DateUtil(day.getValue(),month.getValue(),year.getValue());215         return newDate;216     }217     public boolean compareDates(DateUtil date){218         if(this.year.getValue() > date.year.getValue())219             return true;220         else if(this.year.getValue() < date.year.getValue())221             return false;222         else{223             if(this.month.getValue() > date.month.getValue())224                 return true;225             else if(this.month.getValue() < date.month.getValue())226                 return false;227             else{228                 if(this.day.getValue() > date.day.getValue())229                     return true;230                 else231                     return false;232             }233         }234     }235     public boolean equalTwoDates(DateUtil date){236         if(this.year.getValue() == date.year.getValue() && this.month.getValue() == date.month.getValue() && this.day.getValue() == date.day.getValue())237             return true;238         else239             return false;240     }241    public int getDaysofDates(DateUtil date){242         int n = 0;int flag = 0;243         if(this.compareDates(date))244             flag = 1;245         else246             flag = 0;247        248 249          if(flag == 0) {250              251        252           for( ; this.equalTwoDates(date) == false ; n++){253               if(month.getValue() != 12){254                 if(month.getValue() == 2){255                     if(year.isLeapYear()){256                         if(day.getValue() != 29)257                             day.dayIncrement();258                         else{259                             setDayMin();260                             month.monthIncrement();261                         }         262                     }263                     else{//不是闰年264                         if(day.getValue() != 28)265                             day.dayIncrement();266                         else{267                             setDayMin();268                             month.monthIncrement();269                         }270                     }271                 }//2月272                 else{//不是二月273                     if(month.getValue() == 1 || month.getValue() == 3 || month.getValue() == 5 || month.getValue() == 7 || month.getValue() == 8 || month.getValue() == 10){274                         if(day.getValue() != 31)275                             day.dayIncrement();276                         else{277                             setDayMin();278                             month.monthIncrement();279                         }280                             281                     }282                     else {283                         if(day.getValue() != 30)284                             day.dayIncrement();285                         else{286                             setDayMin();287                             month.monthIncrement();288                         }289                     }290       291                 }292             }293             else{ //是12月294                 if(day.getValue() != 31)295                     day.dayIncrement();296                 else{297                     setDayMin();298                     month.resetMin();299                     year.yearIncrement();300                 }301             }302         }303           return n;  304      }305     //if306         else{307              for( ; this.equalTwoDates(date) == false ; n++){308                 if(month.getValue() == 1){309                   if(day.getValue() == 1){310                      this.setDayMax();311                      month.resetMax();312                      year.yearReduction();313                  }314                  else{315                      day.dayReduction();316                  }317              } 318              else {319                      if(day.getValue() == 1){320                          month.monthReduction();321                          this.setDayMax();322                      }323                      else324                          day.dayReduction();325                  }    326             }327              return n;328         }329       330     }331     public String showDate(){332         String str = "" + year.getValue() + "-" + month.getValue() + "-" + day.getValue();333         return str;334     }335 }336 337 class Day{338     private int value;339     340     Day(){341         342     }343     Day(int Value){344         value = Value;345     }346     347     public int getValue(){348         return value;349     }350     public void setValue(int value){351         this.value = value;352     }353     public void dayIncrement(){354         value++;355     }356     public void dayReduction(){357         value--;358     }359 }360 361 class Month{362     private int value;363    364     Month(){365         366     }367     Month(int Value){368         this.value = Value;369     }370     371     public int getValue(){372         return value;373     }374     public void setValue(int value){375          this.value = value; 376     }377     public void resetMin(){378         value = 1;379     }380     public void resetMax(){381         value = 12;382     }383     public boolean validate(){384         if(value >= 1 && value <= 12)385             return true;386         else387             return false;388     }389     public void monthIncrement(){390         value++;391     }392     public void monthReduction(){393         value--;394     }395 }396 397 class Year{398     private int value;399     400     Year(){401         402     }403     Year(int value){404         this.value = value;405     }406     407     public int getValue(){408         return value;409     }410     public void setValue(int value){411         this.value = value;412     }413     public boolean isLeapYear(){414         if((value % 4 == 0 && value % 100 != 0) || value % 400 == 0)415             return true;416         else417             return false;418     }419     public boolean validate(){420         if(value >= 1820 && value <= 2020)421             return true;422         else423             return false;424     }425     public void yearIncrement(){426         value++;427     }428     public void yearReduction(){429         value--;430     }431 }432         433         
View Code

这道题和之前那到题虽然题目类似,但是类与类之间的关系不一样。DateUtil类中有Day,Mnoth和Year对象,它们之间的关系为DateUtil类与Day类,Month类,Year类都聚合,而Day,Month,Year之间没有关系,符合迪米特法则,类的耦合性更低。

现在在DateUtil类中,就可以用this.属性.方法直接调用想用的方法了。

笔者在DateUtil类中添加有关月份的数组,便于DateUtil的对象直接使用。通过这个题目,我学到了迪米特法则的使用,降低类与类之间的耦合性,使得程序易于维护。

生成的类图如下:

题目集六.

7-1 菜单计价程序-4分数100作者蔡轲单位南昌航空大学

本体大部分内容与菜单计价程序-3相同,增加的部分用加粗文字进行了标注。

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的桌号从小到大的顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计(本内容与计价程序之前相同,其他类根据需要自行定义):

菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu {

Dish[] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

点菜记录类:保存订单上的一道菜品记录

Record {

int orderNum;//序号

Dish d;//菜品\\

int portion;//份额(1/2/3代表小/中/大份)

int getPrice()//计价,计算本条记录的价格

}

订单类:保存用户点的所有菜的信息。

Order {

Record[] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

本次课题比菜单计价系列-3增加的异常情况:

1、菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish"

2、桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error"

3、同一桌菜名、份额相同的点菜记录要合并成一条进行计算,否则可能会出现四舍五入的误差。

4、重复删除,重复的删除记录输出"deduplication :"+序号。

5、代点菜时,桌号不存在,输出"Table number :"+被点菜桌号+" does not exist";本次作业不考虑两桌记录时间不匹配的情况。

6、菜谱信息中出现重复的菜品名,以最后一条记录为准。

7、如果有重复的桌号信息,如果两条信息的时间不在同一时间段,(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)以内算统一时段),此时输出结果按不同的记录分别计价。

8、重复的桌号信息如果两条信息的时间在同一时间段,此时输出结果时合并点菜记录统一计价。前提:两个的桌号信息的时间都在有效时间段以内。计算每一桌总价要先合并符合本条件的饭桌的点菜记录,统一计价输出。

9、份额超出范围(1、2、3)输出:序号+" portion out of range "+份额,份额不能超过1位,否则为非法格式,参照第13条输出。

10、份数超出范围,每桌不超过15份,超出范围输出:序号+" num out of range "+份数。份数必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

11、桌号超出范围[1,55]。输出:桌号 +" table num out of range",桌号必须为1位或多位数值,最高位不能为0,否则按非法格式参照第16条输出。

12、菜谱信息中菜价超出范围(区间(0,300)),输出:菜品名+" price out of range "+价格,菜价必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

13、时间输入有效但超出范围[2022.1.1-2023.12.31],输出:"not a valid time period"

14、一条点菜记录中若格式正确,但数据出现问题,如:菜名不存在、份额超出范围、份数超出范围,按记录中从左到右的次序优先级由高到低,输出时只提示优先级最高的那个错误。

15、每桌的点菜记录的序号必须按从小到大的顺序排列(可以不连续,也可以不从1开始),未按序排列序号的输出:"record serial number sequence error"。当前记录忽略。(代点菜信息的序号除外)

16、所有记录其它非法格式输入,统一输出"wrong format"

17、如果记录以“table”开头,对应记录的格式或者数据不符合桌号的要求,那一桌下面定义的所有信息无论正确或错误均忽略,不做处理。如果记录不是以“table”开头,比如“tab le 55 2023/3/2 12/00/00”,该条记录认为是错误记录,后面所有的信息并入上一桌一起计算。

本次作业比菜单计价系列-3增加的功能:

菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+基础价格+"T"

例如:麻婆豆腐 9 T

菜价的计算方法:

周一至周五 7折, 周末全价。

注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:

计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。

最后将所有记录的菜价累加得到整桌菜的价格。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价

输入样例:

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

麻婆豆腐 12油淋生菜 9 Ttable 31 2023/2/1 14/20/001 麻婆豆腐 1 162 油淋生菜 1 22 delete2 deleteend

输出样例:

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

table 31: 1 num out of range 162 油淋生菜 18deduplication 2table 31: 0 0

输入样例1:

份数超出范围+份额超出范围。例如:

麻婆豆腐 12油淋生菜 9 Ttable 31 2023/2/1 14/20/001 麻婆豆腐 1 162 油淋生菜 4 2end

输出样例1:

份数超出范围+份额超出范围。例如:

table 31: 1 num out of range 162 portion out of range 4table 31: 0 0

输入样例2:

桌号信息错误。例如:

麻婆豆腐 12油淋生菜 9 Ttable a 2023/3/15 12/00/001 麻婆豆腐 1 12 油淋生菜 2 1end

输出样例2:

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

wrong format

输入样例3:

混合错误:桌号信息格式错误+混合的菜谱信息(菜谱信息忽略)。例如:

麻婆豆腐 12油淋生菜 9 Ttable 55 2023/3/31 12/000/00麻辣香锅 151 麻婆豆腐 1 12 油淋生菜 2 1end

输出样例3:

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

wrong format

输入样例4:

错误的菜谱记录。例如:

麻婆豆腐 12.0油淋生菜 9 Ttable 55 2023/3/31 12/00/00麻辣香锅 151 麻婆豆腐 1 12 油淋生菜 2 1end

输出样例4:

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

wrong formattable 55: invalid dish麻婆豆腐 does not exist2 油淋生菜 14table 55: 14 10

输入样例5:

桌号格式错误(以“table”开头)+订单格式错误(忽略)。例如:

麻婆豆腐 12油淋生菜 9 Ttable a 2023/3/15 12/00/001 麻婆 豆腐 1 12 油淋生菜 2 1end

输出样例5:

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

wrong format

输入样例6:

桌号格式错误,不以“table”开头。例如:

麻婆豆腐 12油淋生菜 9 Ttable 1 2023/3/15 12/00/001 麻婆豆腐 1 12 油淋生菜 2 1tab le 2 2023/3/15 12/00/001 麻婆豆腐 1 12 油淋生菜 2 1end

输出样例6:

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

table 1: 1 麻婆豆腐 122 油淋生菜 14wrong formatrecord serial number sequence errorrecord serial number sequence errortable 1: 26 17

这个题目比之前的题目添加了更多的异常情况,测试点也变得更多,笔者没有写出来。我的代码如下:

import java.util.*;public class Main{       public static void main (String[] args){        Scanner input = new Scanner(System.in);                int dishFlag = 0;        int tableNum = 0;        String[] str= new String[100];//输入的字符串数组                Menu menu = new Menu();                      Tables tables = new Tables();//桌子数组             int tableFlag = -1;//桌子号                int i = -1;        do {            i++;            str[i] = input.nextLine();                        //System.out.println(str[i-1]);        }while(!str[i].matches("end"));//输入信息                //菜单处理        int dishNum = 0;        for(i = 0  ; i < str.length ; i++) {            if(!(str[i].charAt(0) == "t")){                String[] dishString = str[i].split(" ");                if(!dishString[1].matches("[0-9]|[1-9][0-9]|[1-9][0-9][0-9]")) {                    System.out.println("wrong format");                }                else {                    if(Integer.parseInt(dishString[1]) > 0 && Integer.parseInt(dishString[1] ) < 300) {                        menu.addDish(dishString[0], Integer.parseInt(dishString[1]));                        if(dishString.length == 3)                            menu.getDishs().get(dishNum).setSpecial(dishString[2]);                                                else                            menu.getDishs().get(dishNum).setSpecial("F");                                                dishNum++;                        }                                                            else {//菜价超出范围                        System.out.println(dishString[0] + " price out of range " + dishString[1]);                                        }                }                                            }            if(str[i].charAt(0) == "t") {//到了桌号标识                dishFlag = i-1;//菜单的下标                break;            }                        }                //处理桌号        for( i = dishFlag + 1; i < str.length ; i++) {            String[] tableString  = str[i].split(" ");                        if(str[i].charAt(0) == "t") {//桌号标识                                if(tableString[0].matches("table")) {                                        if(!tableString[1].matches("[1-9]|[1-9][0-9]|[1-9][0-9][0-9]") ) {                        System.out.println("wrong format");                    }                    else {//桌号是数字                        if(!(Integer.parseInt(tableString[1]) >= 1) && !( Integer.parseInt(tableString[1]) <= 55) ){                            System.out.println(tableString[1] + " table num out of range");                        }                        else {                                                        tables.addATable();                            tables.getTables().get(tableNum).setTableNum(Integer.parseInt(tableString[1]));                            tables.getTables().get(tableNum).setTime1(tableString[2]);                            tables.getTables().get(tableNum).setTime2(tableString[3]);                            System.out.println(tableString[0] +" "+ tableString[1] +":");                                                    }                    }                                                             //else if(tableString[2].matches("[1-2][1-9][1-9][1-9]/[]"))                                    }                else {//桌号标识错误                                    }                                            }                        if(!(str[i].charAt(0) == "t") && !str[i].contains("delete") && tableString.length == 4) {//点菜记录处理                boolean recordIsTrue = true;                        if(tableString.length == 2) {//混杂的菜谱信息,                    System.out.println("invalid dish");                    continue;//忽略这条菜谱                }                if(tableString.length == 4) {//点菜记录                        if(!tableString[2].matches("[1-9]")) {//份额格式错误                            recordIsTrue = false;                            System.out.println("wrong format");//                                        }                        if(tableString[2].matches("[1-9]")) {//份额为数值                            if(menu.searchDish(tableString[1]) != null) {//找到了菜名                                    if(menu.searchDish(tableString[1]).getSpecial() == "T") { //特价菜                                        if((tableString[2] != "1" || tableString[2] != "3")) {                                            System.out.println(tableString[0] + "portion out of range" + tableString[2]);                                            recordIsTrue = false;                                        }                                        else {//普通菜                                            if((tableString[2] != "1" || tableString[2] != "2" || tableString[2] != "3")) {                                                System.out.println(tableString[0] + "portion out of range" + tableString[2]);                                                recordIsTrue  = false ;                                            }                                        }                                                                }                            }                            else {                                                            }                                                                                    }                        if(!tableString[3].matches("[1-9]|[1-9][0-9]")) {//份数非法                            recordIsTrue = false;                            System.out.println("wrong format");                        }                        if(tableString[3].matches("[1-9]|[1-9][0-9]")) {//份数越界                            if(!(Integer.parseInt(tableString[3]) >= 1 && Integer.parseInt(tableString[3]) <= 15)) {                                System.out.println(tableString[0] + " num out of range " + tableString[3]);                                recordIsTrue = false;                            }                        }                if(tableString.length == 4 && recordIsTrue == true) {//添加点菜记录                    tables.getTables().get(tableNum).getOrder().addARecord(Integer.parseInt(tableString[0]),                             tableString[1], Integer.parseInt(tableString[2]), Integer.parseInt(tableString[3]));                }                            }//点菜结束            if(str[i].contains("delete") && tableString.length == 2) {//删除记录                tables.getTables().get(tableNum).getOrder().delARecordByOrderNum(Integer.parseInt(tableString[0]));            }                            if(str[i].matches("end")) {                break;            }          }//点菜记录的处理                                    }              }}class Dish {     String name;//菜品名称    int unit_price;//单价    String special ;//特价菜标识       Dish(){            }    Dish(String name,int unit_price){        this.name = name;        this.unit_price = unit_price;    }        public String getName() {        return this.name;    }        public void setName(String name) {        this.name =  name;    }    public int  getUnit_Price() {        return this.unit_price;    }    public void setUnit_Price(int unit_price) {        this.unit_price = unit_price;    }    public String getSpecial() {        return special;    }    public void setSpecial(String special) {        this.special = special;    }    public int getPrice(int portion){//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)        int result = 0;        if(portion == 1)            result = unit_price*1;        if(portion == 2)            result =  (int)(unit_price*1.5);        if(portion == 3)            result = unit_price*2;        return result;    }}class Menu{    private  ArrayList dishs = new ArrayList<>() ;//菜品数组,保存所有菜品信息    private int dishNum = 0;           Menu(){        super();    }            public ArrayList getDishs() {        return dishs;    }    public void setDishs(ArrayList dishs) {        this.dishs = dishs;    }    public  Dish searchDish(String dishName){//根据菜名在菜谱中查找菜品信息,返回Dish对象。        for(int i = 0; i < dishs.size() ; i++){            if(dishs.get(i).getName() == dishName){                return dishs.get(i);            }                      }        return null;    }       public void addDish(String dishName,int unit_price){//添加一道菜品信息        Dish dish = new Dish();        dish.setName(dishName);        dish.setUnit_Price(unit_price);        dishs.add(dish);            }    }class Table{        int  tableNum;//桌号    String time1;//日期    String time2;//时间    Order order = new Order();//点菜记录    String[] delRecord = new String[3];//删除记录    String[] addRecord = new String[3];//代点菜记录    Table(){            }        public Table(int tableNum, String time1, String time2, Order order, String[] delRecord, String[] addRecord) {        super();        this.tableNum = tableNum;        this.time1 = time1;        this.time2 = time2;        this.order = order;        this.delRecord = delRecord;        this.addRecord = addRecord;    }    public int getTableNum() {        return tableNum;    }    public void setTableNum(int tableNum) {        this.tableNum = tableNum;    }    public String getTime1() {        return time1;    }    public void setTime1(String time1) {        this.time1 = time1;    }    public String getTime2() {        return time2;    }    public void setTime2(String time2) {        this.time2 = time2;    }    public Order getOrder() {        return order;    }    public void setOrder(Order order) {        this.order = order;    }    public String[] getDelRecord() {        return delRecord;    }    public void setDelRecord(String[] delRecord) {        this.delRecord = delRecord;    }    public String[] getAddRecord() {        return addRecord;    }    public void setAddRecord(String[] addRecord) {        this.addRecord = addRecord;    }    }class Time{    public static boolean CheckTime1Validity(String time1) {        String[] str = time1.split("/");        if(str[0].matches("[1-9][0-9][0-9][0-9]") &&                 str[1].matches("[1-9]|[1-9][0-9]") && str[2].matches("[1-9]|[1-9][0-9]")) {            return true;        }        else {            return false;        }                }    public static boolean CheckTime1Range(String time1) {        String[] str = time1.split("/");        int year = Integer.parseInt(str[0]);        int month = Integer.parseInt(str[1]);        int day = Integer.parseInt(str[2]);        int[] mon_Max = {0,31,28,31,30,31,30,31,31,30,31,30,31};        if(year >= 2022 && year <= 2023 && month >= 1 && month <= 12 && day >=1 && day <= mon_Max[month]){            return true;                    }        else            return false;    }    public static boolean CheckTime2Validity(String time2) {        String[] str = time2.split("/");        if(str[0].matches("[1-9]|[1-9][0-9]") &&                 str[1].matches("[1-9]|[1-9][0-9]") && str[2].matches("[1-9]|[1-9][0-9]")) {            return true;        }        else            return false;    }    public static boolean CheckTime2Range(String time2){        String[] str = time2.split("/");        int hour = Integer.parseInt(str[0]);        int minute = Integer.parseInt(str[1]);        int second = Integer.parseInt(str[2]);        if(hour > 0 && hour < 23 && minute > 0 && minute < 60 && second > 0 && second < 60)            return true;        else            return false;            }}class Tables{    ArrayList tables = new ArrayList<>();    public Tables() {        super();        // TODO 自动生成的构造函数存根    }    public Tables(ArrayList
tables) { super(); this.tables = tables; } public ArrayList
getTables() { return tables; } public void setTables(ArrayList
tables) { this.tables = tables; } public void addATable() { Table table = new Table(); tables.add(table); }}class Record{//点菜记录 int orderNum;//序号 Dish d;//菜品 int portion;//份额(1/2/3代表小/中/大份) int num;//份数 Record(){ } public Record(int orderNum, Dish d, int portion, int num) { super(); this.orderNum = orderNum; this.d = d; this.portion = portion; this.num = num; } public int getOrderNum() { return orderNum; } public void setOrderNum(int orderNum) { this.orderNum = orderNum; } public Dish getD() { return d; } public void setD(Dish d) { this.d = d; } public int getPortion() { return portion; } public void setPortion(int portion) { this.portion = portion; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public int getPrice(){//计价,计算本条记录的价格 int result; result = d.getPrice(portion)*num; return result; }}class Order{//保存用户点的所有菜的信息。//点菜记录 ArrayList records = new ArrayList<>();//保存订单上每一道的记录 private int RecordNum = 0; public Record getRecord(int i) { return records.get(i); } public int getTotalPrice(){//计算订单的总价 int sum = 0;int i = 0 ; for(i = 0; i < records.size();i++){ sum += records.get(i).getPrice(); } return sum; } public void addARecord(int orderNum,String dishName,int portion,int num){//添加一条菜品信息 records.get(RecordNum).setOrderNum(orderNum); records.get(RecordNum).getD().setName(dishName); records.get(RecordNum).setPortion(portion); records.get(RecordNum).setNum(num); RecordNum++; } public void delARecordByOrderNum(int orderNum){//根据序号删除一条记录 for(int i = 0; i < records.size(); i++) { if(records.get(i).getOrderNum() == orderNum) { records.remove(i); } } } public Record findRecordByNUm(int orderNum){////根据序号查找一条记录 for(int i = 0 ; i < records.size() ; i++) { if(records.get(i).getOrderNum() == orderNum) { return records.get(i); } } return null; } }View Code

运行结果如上图:

只有一两个测试点对了,导致这个题目几乎没有分。

一开始写的时候,我是想着先写完后面具体的类的具体方法,最后再来写main类中的具体的逻辑。我的思路是先一行行得输入,遇到这个字符串为“end”时,就结束输入的循环,然后进行判断的操作:

若第一个字符不是t,则该行为菜单,菜单包含很多条菜;如果按空格切开来为2个,则为普通菜;如果切开来为3个,则为特殊菜。然后继续循环判断下一条字符串。如果字符串第一个字符为t,则跳出之前的循环,进入一个新的循环,之前的字符串都判定为菜单字符串;在新循环里,若该行第一个字符是t,则该行是桌号标识字符串,存在做好标识数组中;若该行不含delete且切开来是四个,则该行是点菜信息;若该行含有delete,且切开来是两行,则该行是删除记录,删除相应的菜谱信息;若该行含有“table”且切开来为6行,则该字符串为代点菜信息。如此循环,直到该字符串为end.

这个题目只有两个异常情况对了,正常的情况一个都没对;这还是因为我对类与类之间的关系还不够熟悉,再加上题目有一定难度,并且其他同学不想写的呼声很大,包括我自己也偷懒,写到一半就半途而废,所以这道题的分数就很低。

相应的类图如下:

三.踩坑心得

1.在写去除重复的数据这个题目的时候,我的源码如下:

用的是后接法,把有重复的数据变成0,然后再输出不含0的项就行了,但是这个方法再N很大的时候就不行了,会运行超时。

于是我就用了hashset和linkedhashset来避免有重复的数据,这样就不会出现N很大会运行超时的情况。

2.在写单词统计与排序这道题的时候,我一开始想着直接按照空格,逗号,句号来切割字符串:

结果发现它并不会直接按照这些切割成一个个单词,而是返回空指针;后面我就转变了思路,先切割空格,再看切割出的单词是否含有句号或者逗号,然后删掉逗号和句号,最后按照单词的长度和大小来进行排序(可能是我正则表达式用的有问题),最后才得到正确答案。

3.在写日期问题面向对象设计的题目时,在DateUtil调用Month,Day和Year对象的时候,我一开始写的是date.day.month.year.getValue();导致运行的时候都是错误,后面问了同学才知道。每个类里的get方法可以返回该类含有的对象,于是将代码改为date.getDay().getMonth().getYear().getValue();这样就可以一直调用了。

四.改进建议

1.在写题目集四的判断两个日期之间的天数的时候,我的输出的函数如下:

一个是前面的日期更大的情况,另一个是前面的天数更小的情况。两个输出都有相同的部分,可以改成先根据日期的大小,判断两日期之间的天数是正数还是负数,对两个日期的天数进行处理 ,然后在进行输出,这样就不会有重复的代码。

2.题目集5的7-5判断日期是否合理的方法:

我是先判断年是否合理,再判断月份是否合理,最后再判断天数是否合理,后续可以改成if(day.getMonth().getYear()).validate() && day.getMonth().validate() && day.validate())直接判断三个值是否合法,否则返回false;这样比之前的更简洁,也不容易搞混括号的范围。

在求下N天的方法时

1  public DateUtil getNextNDays(int n){ 2          for( ; n > 0 ; n--){ 3             if(month.getValue() != 12) {//不是12月 4                 if(month.getValue() == 2){//二月 5                     if(year.isLeapYear()){ 6                         if(day.getValue() != 29) 7                             day.dayIncrement(); 8                         else{ 9                             setDayMin();10                             month.monthIncrement();11                         12                         }13                     }14                     else{//不是闰年15                         if(day.getValue() != 28)16                             day.dayIncrement();17                         else{18                             setDayMin();19                             month.monthIncrement();20                         }21                     }22                 }//2月23                 else{//不是二月24                     if(month.getValue() == 1 || month.getValue() == 3 || month.getValue() == 5 || month.getValue() == 7 || month.getValue() == 8 || month.getValue() == 10){25                         if(day.getValue() != 31)26                             day.dayIncrement();27                         else{28                             this.setDayMin();29                             month.monthIncrement();30                         }31                             32                     }33                     else {34                         if(day.getValue() != 30)35                             day.dayIncrement();36                         else{37                             this.setDayMin();38                             month.monthIncrement();39                 40                         }41                     }42       43                 }44             }45             else{ //是12月46                 if(day.getValue() != 31)47                     day.dayIncrement();48                 else{49                     this.setDayMin();50                     month.resetMin();51                     year.yearIncrement();52                 }53             }54                55         }//n56         DateUtil newDate = new DateUtil(day.getValue(),month.getValue(),year.getValue());57         return newDate;58     }
View Code

我没次都是判断最后的日期不是临界值的时候,就让day++;后续可以改成一开始就让day++,再判断是否为临界值,如果是临界值的话,就让day等于1,然后月份和年也做相应的变换,这样可以节省很多行的day.dayIncrement();节省空间。

五.总结

1.首先,通过这几次作业,我已经对类与对象的关系有了基本了解,类与类之间的关系有关联,依赖,聚合等,类可以实例化一个或多个对象,一个类中可以含有另一个类的对象,这样就形成了聚合关系。

2.题目集4的7-3去除重复数据,我知道了有LinkedHashSet这个工具,可以让存储的数据不重复,并且保持输入顺序的不变性,这在很多情况下就可以不用进行删除的步骤。

3.题目集4的最后一题,我知道了有关时间的很多方法,LocalDate类中比较两个日期之间的天数,返回的是相差的天数,有正也有负。

4.题目集5主要考察了正则表达式的使用,正则表达式是符合某种规则的字符串,只要满足这种规则的字符串就会返回true,利用这个可以检验QQ号,账号名,学号,验证码等有一定规律的字符串。

5.题目集5的日期类问题,我了解了类与类之间的关系,以及如何正确地设计类与类之间的关系。一个类可以包含另一个类中的对象,比如DateUtil类中含有Day类,Day类中含有Month类,Month类中含有Year类,它们之间的关系为聚集。

                 

关键词: