pta题目集4-6的总结

发布时间 2023-04-27 16:09:25作者: 一只blog程序猿

(1)前言:三次题目集的题目数目总体不多,分别为七题、六题、一题。题目的难度减少,但是难度却逐渐增加,知识点涉及的也更广。第四次题目集考察的知识点主要是字符串的使用以及数组,题目的难度在第一题到第四题,这四题主要考察逻辑,而不是语法,后面三题主要考查语法。第五次题目集考察的知识点主要是正则表达式、类、字符串语法和数组语法的使用和聚合的使用。第六次题目集虽然只有一道题目,但这道题目是由菜单计价程序叠加四次的题目,主要考察类和逻辑,测试点十分的多。

(2)设计与分析:

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
油淋生菜 9
table 1 2023/3/22 12/2/3
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end
 

输出样例:

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

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

输入样例1:

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

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

输出样例1:

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

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

输入样例2:

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

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

输出样例2:

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

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

输入样例3:

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

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/5 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
7 delete
end
 

输出样例3:

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

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

输入样例4:

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

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/3 19/5/12
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 4 麻婆豆腐 1 1
7 delete
end
 

输出样例4:

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

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
4 table 2 pay for table 1 12
delete error;
table 1: 63
table 2: 75
 
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

源码:

  1 import java.util.*;
  2 public class Main {
  3     public static void main(String[] args) {
  4         Scanner input = new Scanner(System.in);
  5         Menu menu = new Menu();
  6         Table[] tablemes = new Table[10];
  7         int dishAmount = 0;//菜单菜的数目
  8         int orderAmount = 0;//点菜记录的数目(包括带点菜的记录)
  9         Dish dish;
 10         int tableAmount = 0;//桌子的数目
 11         int count;//数组长度
 12         String[] temp;//输入字符串去除空格后的数组
 13         int a1,a2,a3,a4,a5;
 14         while (true) {
 15             String string = input.nextLine();
 16             temp = string.split(" ");
 17             if(string.equals("end"))
 18                 break;
 19             count = temp.length;
 20             if (count == 2) {
 21                 if (temp[1].equals("delete")) {
 22                         a1 = Integer.parseInt(temp[0]);
 23                         if (tablemes[tableAmount].order.delARecordByOrderNum(a1) == 0) {
 24                             System.out.println("delete error;");
 25                         } else {
 26                                 int c = tablemes[tableAmount].order.delARecordByOrderNum(a1);//要删除序号的点菜记录的价格
 27                                 tablemes[tableAmount].order.sum -= c;//删除记录后那桌的未打折的总价格
 28                         }
 29                 } else{
 30                     a2 = Integer.parseInt(temp[1]);
 31                     menu.dishs[dishAmount] = menu.addDish(temp[0], a2);//添加新的菜到菜单里面
 32                     dishAmount++;//菜的数目加1
 33                 }
 34             }
 35             else if (count == 4) {
 36                 if (temp[0].equals("table")){
 37                     tableAmount++;//桌子数加一
 38                     orderAmount = 0;//每个桌子的点菜记录数目不同,创建一个新的类时需要重置数目
 39                     tablemes[tableAmount] = new Table(temp[1], temp[2], temp[3]);//创建一个新的类
 40                     tablemes[tableAmount].processTime();//处理桌子的日期和时间
 41                     tablemes[tableAmount].setDiscount();//设置每个桌子时间对应的菜的折扣
 42                     System.out.println("table " + temp[1] + ": ");
 43                 } else {
 44                         a3 = Integer.parseInt(temp[0]);//序号
 45                         a4 = Integer.parseInt(temp[2]);//份额
 46                         a5 = Integer.parseInt(temp[3]);//份数
 47                         tablemes[tableAmount].order.addARecord(a3, temp[1],a4 , a5);//使用函数给点菜记录赋予相关的序号、菜名、份额、份数,将该条记录添加到总记录中
 48                         dish = menu.searthDish(temp[1]);//找点菜记录的菜名,存在菜名,返回dish,否则返回null
 49                         if(dish==null){
 50                             System.out.println(temp[1]+" does not exist");
 51                         }
 52                         if (dish != null) {
 53                             tablemes[tableAmount].order.records[orderAmount].d = dish;//让记录的菜等于dish,以方便获得菜的价钱
 54                             int a = tablemes[tableAmount].order.records[orderAmount].getPrice();//计算记录的价格
 55                             System.out.println(tablemes[tableAmount].order.records[orderAmount].orderNum + " " + dish.name + " " + a);
 56                             tablemes[tableAmount].order.sum += a;//把该记录的价格加到该桌子的总价格中
 57                         }
 58                         orderAmount++;//点菜记录加一
 59                 }
 60             }
 61             else if (count == 5){
 62                 a1 = Integer.parseInt(temp[1]);//序号
 63                 a2 = Integer.parseInt(temp[3]);//份额
 64                 a3 = Integer.parseInt(temp[4]);//份数
 65                 tablemes[tableAmount].order.addARecord(a1, temp[2], a2, a3);//使用函数给代点菜记录赋予相关的序号、菜名、份额、份数,将该条记录添加到总记录中
 66                 dish = menu.searthDish(temp[2]);//找点菜记录的菜名,存在菜名,返回dish,否则返回null
 67                 if(dish==null){
 68                     System.out.println(temp[2]+" does not exist");
 69                 }
 70                 if (dish != null){
 71                     tablemes[tableAmount].order.records[orderAmount].d = dish;//让记录的菜等于dish,以方便获得菜的价钱
 72                     int b = tablemes[tableAmount].order.records[orderAmount].getPrice();////计算记录的价格
 73                     System.out.println(temp[1] + " table " + tablemes[tableAmount].tableNum + " pay for table " + temp[0] + " " + b);
 74                     tablemes[tableAmount].order.sum += b;//把该记录的价格加到该桌子的总价格中
 75                 }
 76                 orderAmount++;//点菜记录加一
 77             }
 78         }
 79         for(int i = 1; i < tableAmount + 1; i++){
 80             if(tablemes[i].getDiscount()>0){
 81                 System.out.println("table " + tablemes[i].tableNum + ": "+Math.round(tablemes[i].order.getTotalPrice()*tablemes[i].getDiscount()));
 82             }
 83             else System.out.println("table " + tablemes[i].tableNum + " out of opening hours");
 84         }
 85     }
 86 }
 87 class Dish {
 88     String name;
 89     int unit_price;
 90     int getPrice(int portion) {
 91         if (portion == 1) return unit_price;
 92         else if (portion == 2) return Math.round((float) (unit_price * 1.5));
 93         else return 2*unit_price;
 94     }
 95 }
 96 class Menu {
 97     Dish[] dishs = new Dish[10];
 98     int dishCount = 0;
 99     Dish searthDish(String dishName){
100         for(int i=dishCount-1;i>=0;i--){
101             if(dishName.equals(dishs[i].name)){
102                 return dishs[i];
103             }
104         }
105         return null;
106     }
107     Dish addDish(String dishName,int unit_price){
108         Dish dish = new Dish();
109         dish.name = dishName;
110         dish.unit_price = unit_price;
111         dishCount++;
112         return dish;
113     }
114 }
115 class Record {
116     int orderNum;
117     Dish d = new Dish();
118     int num = 0;
119     int portion;
120     int getPrice(){
121         return d.getPrice(portion)*num;
122     }
123 }
124 class Order {
125     Record[] records = new Record[10];
126     int count = 0;
127 
128     int sum;
129     void addARecord(int orderNum,String dishName,int portion,int num){
130         records[count] = new Record();
131         records[count].d.name = dishName;
132         records[count].orderNum = orderNum;
133         records[count].portion = portion;
134         records[count].num = num;
135         count++;
136     }
137     int getTotalPrice(){
138         return sum;
139     }
140     int delARecordByOrderNum(int orderNum){
141         if(orderNum>count||orderNum<=0){
142             return 0;
143         }else {
144             return records[orderNum - 1].getPrice();
145         }
146     }
147     Record findRecordByNum(int orderNum) {
148         for (int i = count - 1; i >= 0; i--) {
149             if (orderNum == records[i].orderNum) {
150                 return records[i];
151             }
152         }
153         return null;
154     }
155 }
156 class Table {
157     int tableNum;
158     String Date;
159     String tableTime;
160     public Table() {
161     }
162 
163     public Table(String tableNum, String date, String tableTime) {
164         this.tableNum = Integer.parseInt(tableNum);
165         Date = date;
166         this.tableTime = tableTime;
167     }
168     int year,month,day,week,hh,mm,ss;
169     Order order = new Order();
170     float discount = -1;
171     void processTime(){
172         String[] temp1 = Date.split("/");
173         String[] temp2 = tableTime.split("/");
174 
175         year = Integer.parseInt(temp1[0]);
176         month = Integer.parseInt(temp1[1]);
177         day = Integer.parseInt(temp1[2]);
178 
179         Calendar date = Calendar.getInstance();
180         date.set(year, (month-1), day);
181         week = date.get(Calendar.DAY_OF_WEEK);
182         if(week==1)
183             week = 7;
184         else
185             week--;
186         hh = Integer.parseInt(temp2[0]);
187         mm = Integer.parseInt(temp2[1]);
188         ss = Integer.parseInt(temp2[2]);
189 
190     }
191     void setDiscount(){
192         if(week>=1&&week<=5)
193         {
194             if(hh>=17&&hh<20)
195                 discount =0.8F;
196             else if(hh==20&&mm<30)
197                 discount =0.8F;
198             else if(hh==20&&mm==30&&ss==0)
199                 discount =0.8F;
200             else if(hh>=11&&hh<=13||hh==10&&mm>=30)
201                 discount =0.6F;
202             else if(hh==14&&mm<30)
203                 discount =0.6F;
204             else if(hh==14&&mm==30&&ss==0)
205                 discount =0.6F;
206         }
207         else
208         {
209             if(hh>=10&&hh<=20)
210                 discount = 1.0F;
211             else if(hh==9&&mm>=30)
212                 discount = 1.0F;
213             else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
214                 discount = 1.0F;
215         }
216     }
217     float getDiscount(){
218         return discount;
219     }
220 }
7-1 菜单计价-3

我的类图:

报表内容:

解释与心得:

先说题目集4的7-1 菜单计价-3,这题一开始我是嫌麻烦,因为题目长度太长,而且看到好多人都没得分,于是我就没写。但是后面的第六次题目集就是这题的迭代,我就必须要重新审视起来,于是我是先在完成这题的基础上再去写那题,不过只是在这次题目集关闭后的事情了。先说这题的思路吧,首先需要把题目弄懂,然后再写相关的类,很明显有多个桌子,而且每个桌子的属性有桌号、日期和时间,而且菜的折扣和时间有关,所以需要设计一个桌子类来处理这些信息,基本的类题目已经给出。其次是写主类,先要考虑如何输入,格式是如何的,一开始我以为输入的信息是一次性输入,然后把字符串处理为Array,但是发现这样没法处理,所以我用了一个无限循环来处理输入信息,输入一条,处理一条,把输入的每一条字符串都用slip方法处理为数组,然后再根据length来判断是菜单信息还是删除记录以及点菜,最后以"end"结束无限循环。由于这次题目集没有那么多要求,所以当length为2时,并且temp[1]为equals时,就是删除点菜记录;否则就添加到菜单。当length为4,并且temp[0]为tabble时,tabbleAmount加1,因为每个桌子的orderAmount不一样,所以重置orderAmount的数目为0,再新创一个tabble类,再进行有关的信息处理;否则就是点菜,需要添加点菜记录。当length为5时,就是带点菜,需要添加点菜记录。循环结束后,再用一个循环输出。

 

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

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

类图.jpg

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

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

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

输入格式:

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

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

输出格式:

  • 当输入有误时,输出格式如下:
    Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year-month-day
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year-month-day
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    天数值
     

输入样例1:

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

3 2014 2 14 2020 6 14
 

输出样例1:

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

2312
 

输入样例2:

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

2 1935 2 17 125340
 

输出样例2:

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

1591-12-17
 

输入样例3:

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

1 1999 3 28 6543
 

输出样例3:

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

2017-2-24
 

输入样例4:

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

0 2000 5 12 30
 

输出样例4:

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

Wrong Format
 
代码长度限制
16 KB
时间限制
10000 ms
内存限制
64 MB

源码:

  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         int year = 0;
  7         int month = 0;
  8         int day = 0;
  9 
 10         int choice = input.nextInt();
 11 
 12         if (choice == 1) { // test getNextNDays method
 13             int m = 0;
 14             year = Integer.parseInt(input.next());
 15             month = Integer.parseInt(input.next());
 16             day = Integer.parseInt(input.next());
 17 
 18             DateUtil date = new DateUtil(day, month, year);
 19 
 20             if (!date.checkInputValidity()) {
 21                 System.out.println("Wrong Format");
 22                 System.exit(0);
 23             }
 24 
 25             m = input.nextInt();
 26 
 27             if (m < 0) {
 28                 System.out.println("Wrong Format");
 29                 System.exit(0);
 30             }
 31 
 32             System.out.println(date.getNextNDays(m).showDate());
 33         } else if (choice == 2) { // test getPreviousNDays method
 34             int n = 0;
 35             year = Integer.parseInt(input.next());
 36             month = Integer.parseInt(input.next());
 37             day = Integer.parseInt(input.next());
 38 
 39             DateUtil date = new DateUtil(day, month, year);
 40 
 41             if (!date.checkInputValidity()) {
 42                 System.out.println("Wrong Format");
 43                 System.exit(0);
 44             }
 45 
 46             n = input.nextInt();
 47 
 48             if (n < 0) {
 49                 System.out.println("Wrong Format");
 50                 System.exit(0);
 51             }
 52 
 53             System.out.println(date.getPreviousNDays(n).showDate());
 54         } else if (choice == 3) {    //test getDaysofDates method
 55             year = Integer.parseInt(input.next());
 56             month = Integer.parseInt(input.next());
 57             day = Integer.parseInt(input.next());
 58 
 59             int anotherYear = Integer.parseInt(input.next());
 60             int anotherMonth = Integer.parseInt(input.next());
 61             int anotherDay = Integer.parseInt(input.next());
 62 
 63             DateUtil fromDate = new DateUtil(day, month, year);
 64             DateUtil toDate = new DateUtil(anotherDay, anotherMonth, anotherYear);
 65 
 66             if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
 67                 System.out.println(fromDate.getDaysofDates(toDate));
 68             } else {
 69                 System.out.println("Wrong Format");
 70                 System.exit(0);
 71             }
 72         }
 73         else{
 74             System.out.println("Wrong Format");
 75             System.exit(0);
 76         }
 77     }
 78 }
 79 class DateUtil {
 80     private Day day = new Day();
 81 
 82     DateUtil() {
 83 
 84     }
 85 
 86     DateUtil(int d, int m, int y) {
 87         day.setValue(d);
 88         day.getMonth().setValue(m);
 89         day.getMonth().getYear().setValue(y);
 90     }
 91 
 92     Day getDay() {
 93         return day;
 94     }
 95 
 96     void setDay(Day d) {
 97         day = d;
 98     }
 99 
100     public boolean checkInputValidity() {
101         if (day.getMonth().getYear().validate()) {
102             if (day.getMonth().validate()) {
103                 if (day.validate()) {
104                     return true;
105                 } else return false;
106             } else return false;
107         } else return false;
108     }
109 
110     public DateUtil getNextNDays(int m) {
111         int i;
112         long sum = 0;
113         long sum1 = 0;
114         long sum2 = 0;
115         long sum3 = 0;
116         long sum4 = 0;
117         long n = (long) m;
118         DateUtil date1 = new DateUtil();
119         if (day.getMonth().getYear().isLeapYear()) {
120             day.mon_maxnum[1] = 29;
121             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
122                 sum1 += day.mon_maxnum[i];
123             }
124             sum = sum1 + day.getValue();
125             i = 0;
126             if (sum + n <= 366) {
127                 while (sum2 + day.mon_maxnum[i] < sum + n) {
128                     sum2 += day.mon_maxnum[i];
129                     i++;
130                 }
131                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
132                 date1.day.getMonth().setValue(i + 1);
133                 date1.day.setValue((int) (sum + n - sum2));
134             } else {
135                 while (sum4 < sum + n) {
136                     if (day.getMonth().getYear().isLeapYear()) {
137                         sum3 += 366;
138                         day.getMonth().getYear().yearIncrement();
139                         if (day.getMonth().getYear().isLeapYear()) {
140                             sum4 = sum3 + 366;
141                         } else sum4 = sum3 + 365;
142                         day.getMonth().getYear().yearReduction();
143                     } else {
144                         sum3 += 365;
145                         day.getMonth().getYear().yearIncrement();
146                         if (day.getMonth().getYear().isLeapYear()) {
147                             sum4 = sum3 + 366;
148                         } else sum4 = sum3 + 365;
149                         day.getMonth().getYear().yearReduction();
150                     }
151                     day.getMonth().getYear().yearIncrement();
152                 }
153                 i = 0;
154                 sum2 = 0;
155                 if (day.getMonth().getYear().isLeapYear()) day.mon_maxnum[2] = 29;
156                 else day.mon_maxnum[2] = 28;
157                 while ((sum2 + day.mon_maxnum[i]) < (sum + n - sum3)) {
158                     sum2 += day.mon_maxnum[i];
159                     i++;
160                 }
161                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
162                 date1.day.getMonth().setValue(i + 1);
163                 date1.day.setValue((int) (sum + n - sum3 - sum2));
164             }
165         } else {
166             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
167                 sum1 += day.mon_maxnum[i];
168             }
169             sum = sum1 + day.getValue();
170             i = 0;
171             if (sum + n <= 365) {
172                 while (sum2 + day.mon_maxnum[i] < sum + n) {
173                     sum2 += day.mon_maxnum[i];
174                     i++;
175                 }
176                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
177                 date1.day.getMonth().setValue(i + 1);
178                 date1.day.setValue((int) (sum + n - sum2));
179             } else {
180                 while (sum4 < sum + n) {
181                     if (day.getMonth().getYear().isLeapYear()) {
182                         sum3 += 366;
183                         day.getMonth().getYear().yearIncrement();
184                         if (day.getMonth().getYear().isLeapYear()) {
185                             sum4 = sum3 + 366;
186                         } else sum4 = sum3 + 365;
187                         day.getMonth().getYear().yearReduction();
188                     } else {
189                         sum3 += 365;
190                         day.getMonth().getYear().yearIncrement();
191                         if (day.getMonth().getYear().isLeapYear()) {
192                             sum4 = sum3 + 366;
193                         } else sum4 = sum3 + 365;
194                         day.getMonth().getYear().yearReduction();
195                     }
196                     day.getMonth().getYear().yearIncrement();
197                 }
198                 i = 0;
199                 sum2 = 0;
200                 if (day.getMonth().getYear().isLeapYear()) day.mon_maxnum[1] = 29;
201                 else day.mon_maxnum[1] = 28;
202                 while ((sum2 + day.mon_maxnum[i]) < (sum + n - sum3)) {
203                     sum2 += day.mon_maxnum[i];
204                     i++;
205                 }
206                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
207                 date1.day.getMonth().setValue(i + 1);
208                 date1.day.setValue((int) (sum + n - sum3 - sum2));
209             }
210         }
211         return date1;
212     }
213 
214     public DateUtil getPreviousNDays(int m) {
215         int i;
216         long sum = 0;
217         long sum1 = 0;
218         long sum2 = 0;
219         long sum3 = 0;
220         long n = (long) m;
221         DateUtil date2 = new DateUtil();
222         if (day.getMonth().getYear().isLeapYear())
223             day.mon_maxnum[1] = 29;
224         else day.mon_maxnum[1] = 28;
225             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
226                 sum1 += day.mon_maxnum[i];
227             }
228             sum = sum1 + day.getValue();
229             i = 0;
230             if (n < sum) {
231                 while ((sum2 + day.mon_maxnum[i]) < (sum - n)) {
232                     sum2 += day.mon_maxnum[i];
233                     i++;
234                 }
235                 date2.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
236                 date2.day.getMonth().setValue(i + 1);
237                 date2.day.setValue((int) (sum - n - sum2));
238             }
239             else {
240                 while (sum3 <= (n - sum)) {
241                     day.getMonth().getYear().yearReduction();
242                     if (day.getMonth().getYear().isLeapYear()) sum3 += 366;
243                     else sum3 += 365;
244                 }
245                 i = 0;
246                 sum2 = 0;
247                 if (day.getMonth().getYear().isLeapYear()) day.mon_maxnum[1] = 29;
248                 else day.mon_maxnum[1] = 28;
249                 while ((sum2 + day.mon_maxnum[i]) < (sum3 - n + sum)) {
250                     sum2 += day.mon_maxnum[i];
251                     i++;
252                 }
253                 date2.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
254                 date2.day.getMonth().setValue(i + 1);
255                 date2.day.setValue((int) (sum3 - n + sum - sum2));
256             }
257             return date2;
258         }
259 
260     public int getDaysofDates(DateUtil date) {
261         int i, j, k;
262         int sum0 = 0;
263         int sum = 0;
264         int sum1 = 0;
265         int sum2 = 0;
266         int sum3 = 0;
267         int sum4 = 0;
268         if (day.getMonth().getYear().isLeapYear())
269             day.mon_maxnum[1] = 29;
270         else day.mon_maxnum[1]=28;
271             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
272                 sum1 += day.mon_maxnum[i];
273             }
274             sum0 = sum1 + day.getValue();
275             if (date.getDay().getMonth().getYear().isLeapYear()) date.getDay().mon_maxnum[1] = 29;
276             else date.getDay().mon_maxnum[1] = 28;
277             for (j = 0; j < date.getDay().getMonth().getValue() - 1; j++) {
278                 sum2 += date.getDay().mon_maxnum[j];
279             }
280             sum = sum2 + date.getDay().getValue();
281             if (equalTwoDates(date)) return 0;
282             else {
283                 Day day1 = new Day();
284                 if (compareDates(date)) {
285                     if (day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()) return (sum - sum0);
286                     else {
287                         for (k = (day.getMonth().getYear().getValue() + 1); k < date.getDay().getMonth().getYear().getValue(); k++) {
288                             day1.getMonth().getYear().setValue(k);
289                             if (day1.getMonth().getYear().isLeapYear()) sum3 += 366;
290                             else sum3 += 365;
291                         }
292                         if (day.getMonth().getYear().isLeapYear()) return (sum3 + 366 - sum0 + sum);
293                         else return (sum3 + 365 - sum0 + sum);
294                     }
295                 } else {
296                     if (day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()) return (sum0 - sum);
297                     else {
298                         for (k = (date.getDay().getMonth().getYear().getValue() + 1); k < day.getMonth().getYear().getValue(); k++) {
299                             day1.getMonth().getYear().setValue(k);
300                             if (day1.getMonth().getYear().isLeapYear()) sum4 += 366;
301                             else sum4 += 365;
302                         }
303                         if (date.getDay().getMonth().getYear().isLeapYear()) return (sum4 + 366 - sum + sum0);
304                         else return (sum4 + 365 - sum + sum0);
305                     }
306                 }
307             }
308         }
309 
310      public boolean compareDates(DateUtil date){
311             if(day.getMonth().getYear().getValue()<date.getDay().getMonth().getYear().getValue()) return true;
312             else if(day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue()){
313                 if(day.getMonth().getValue()<date.getDay().getMonth().getValue()) return true;
314                 else if(day.getMonth().getValue()==date.getDay().getMonth().getValue()){
315                     if(day.getValue()<date.getDay().getValue()) return true;
316                     return false;
317                 }
318                 return false;
319             }
320             return false;
321         }
322         public boolean equalTwoDates(DateUtil date){
323             if(day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue()&&day.getMonth().getValue()==date.getDay().getMonth().getValue()&&day.getValue()==date.getDay().getValue()) return true;
324             else return false;
325         }
326 
327             public String showDate () {
328                 String s = day.getMonth().getYear().getValue() + "-" + day.getMonth().getValue() + "-" + day.getValue();
329                 return s;
330             }
331 }
332 class Day{
333     private int value;
334     private Month month = new Month();
335     int[] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
336     Day(){
337 
338     }
339 
340     Day(int yearValue,int monthValue,int dayValue){
341         month.setValue(monthValue);
342         month.getYear().setValue(yearValue);
343     }
344 
345     int getValue(){
346         return value;
347     }
348 
349     void setValue(int value){
350         this.value=value;
351     }
352 
353     Month getMonth(){
354         return month;
355     }
356 
357     void setMonth(Month value){
358         month=value;
359     }
360 
361     void resetMin(){
362         value=1;
363     }
364 
365     void resetMax(){
366         if(month.getYear().isLeapYear()){
367             mon_maxnum[1]=29;
368         }
369         value=mon_maxnum[value-1];
370     }
371 
372     boolean validate(){
373         if(month.getYear().isLeapYear()){
374             mon_maxnum[1]=29;
375         }
376         if(value>=1&&value<=mon_maxnum[month.getValue()-1]){
377             return true;
378         }
379         else return false;
380     }
381 
382     void dayIncrement(){
383         value+=1;
384     }
385 
386     void dayReduction(){
387         value-=1;
388     }
389 }
390 
391 class Month{
392     private int value;
393     private Year year = new Year();
394 
395     Month(){
396 
397     }
398 
399     Month(int yearValue,int monthValue){
400         value = monthValue;
401         year.setValue(yearValue);
402     }
403 
404     int getValue(){
405         return value;
406     }
407 
408     void setValue(int value){
409         this.value=value;
410     }
411 
412     Year getYear(){
413         return year;
414     }
415 
416     void setYear(Year year){
417         this.year=year;
418     }
419 
420     void resetMin(){
421         value=1;
422     }
423 
424     void resetMax(){
425         value=12;
426     }
427 
428     boolean validate(){
429         if(value>=1&&value<=12){
430             return true;
431         }
432         else return false;
433     }
434 
435     void monthIncrement(){
436         value+=1;
437     }
438 
439     void monthReduction(){
440         value-=1;
441     }
442 }
443 
444 class Year{
445     private int value;
446 
447     Year(){
448 
449     }
450 
451     Year(int value){
452         this.value=value;
453     }
454 
455     int getValue(){
456         return value;
457     }
458 
459     void setValue(int value){
460         this.value=value;
461     }
462 
463     boolean isLeapYear(){
464         if((value%4==0&&value%100!=0)||(value%400==0)){
465             return true;
466         }
467         else return false;
468     }
469 
470     boolean validate(){
471         if(value>=1900&&value<=2050){
472             return true;
473         }
474         else return false;
475     }
476 
477     void yearIncrement(){
478         value+=1;
479     }
480 
481     void yearReduction(){
482         value-=1;
483     }
484 }
7-5 日期问题面向对象设计(聚合一)

类图:

报表内容:

解释与心得:

做这题需要先把类图里的属性和方法想清楚,而且需要搞清类与类之间的关系,这题的算法和逻辑和题目集3最后一题差不多,只是要求我们使用聚合来实现,而且这题的结构不一样,虽然说我这题看起来满分,但是类图跟题目给出的类图不一样,没有用到聚合,只是关联,而且Main方法和其他几个类是依赖关系,我虽然知道聚合关系怎么用,但是那样会改变该类图的构造方法。

 

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

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

类图.jpg

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

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

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

输入格式:

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

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

输出格式:

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

输入样例1:

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

3 2014 2 14 2020 6 14
 

输出样例1:

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

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

输入样例2:

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

2 1834 2 17 7821
 

输出样例2:

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

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

输入样例3:

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

1 1999 3 28 6543
 

输出样例3:

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

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

输入样例4:

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

0 2000 5 12 30
 

输出样例4:

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

Wrong Format
 
代码长度限制
16 KB
时间限制
10000 ms
内存限制
64 MB

源码:

  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         int year = 0;
  7         int month = 0;
  8         int day = 0;
  9 
 10         int choice = input.nextInt();
 11 
 12         if (choice == 1) { // test getNextNDays method
 13             int m = 0;
 14             year = Integer.parseInt(input.next());
 15             month = Integer.parseInt(input.next());
 16             day = Integer.parseInt(input.next());
 17 
 18             DateUtil date = new DateUtil(year, month, day);
 19 
 20             if (!date.checkInputValidity()) {
 21                 System.out.println("Wrong Format");
 22                 System.exit(0);
 23             }
 24 
 25             m = input.nextInt();
 26 
 27             if (m < 0) {
 28                 System.out.println("Wrong Format");
 29                 System.exit(0);
 30             }
 31             System.out.print(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + m + " days is:");
 32             System.out.println(date.getNextNDays(m).showDate());
 33         } else if (choice == 2) { // test getPreviousNDays method
 34             int n = 0;
 35             year = Integer.parseInt(input.next());
 36             month = Integer.parseInt(input.next());
 37             day = Integer.parseInt(input.next());
 38 
 39             DateUtil date = new DateUtil(year, month, day);
 40 
 41             if (!date.checkInputValidity()) {
 42                 System.out.println("Wrong Format");
 43                 System.exit(0);
 44             }
 45 
 46             n = input.nextInt();
 47 
 48             if (n < 0) {
 49                 System.out.println("Wrong Format");
 50                 System.exit(0);
 51             }
 52             System.out.print(
 53                     date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " previous " + n + " days is:");
 54             System.out.println(date.getPreviousNDays(n).showDate());
 55         } else if (choice == 3) {    //test getDaysofDates method
 56             year = Integer.parseInt(input.next());
 57             month = Integer.parseInt(input.next());
 58             day = Integer.parseInt(input.next());
 59 
 60             int anotherYear = Integer.parseInt(input.next());
 61             int anotherMonth = Integer.parseInt(input.next());
 62             int anotherDay = Integer.parseInt(input.next());
 63 
 64             DateUtil fromDate = new DateUtil(year, month, day);
 65             DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
 66 
 67             if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
 68                 System.out.println("The days between " + fromDate.showDate() +
 69                         " and " + toDate.showDate() + " are:"
 70                         + fromDate.getDaysofDates(toDate));
 71             } else {
 72                 System.out.println("Wrong Format");
 73                 System.exit(0);
 74             }
 75         }
 76         else{
 77             System.out.println("Wrong Format");
 78             System.exit(0);
 79         }
 80     }
 81 }
 82 class DateUtil {
 83     private Year year = new Year();
 84     private Month month = new Month();
 85     private Day day = new Day();
 86 
 87     private int[] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
 88     DateUtil() {
 89 
 90     }
 91 
 92     DateUtil(int y, int m, int d) {
 93         year.setValue(y);
 94         month.setValue(m);
 95         day.setValue(d);
 96     }
 97 
 98     Year getYear() {
 99         return year;
100     }
101 
102     void setYear(Year year) {
103         this.year = year;
104     }
105 
106     Month getMonth(){
107         return month;
108     }
109 
110     void setMonth(Month month){
111         this.month = month;
112     }
113     Day getDay(){
114         return day;
115     }
116 
117     void setDay(Day day){
118         this.day = day;
119     }
120 
121     void setDayMin(){
122         day.setValue(1);
123     }
124 
125     void setDayMax(){
126         if(year.isLeapYear()) mon_maxnum[1]=29;
127         day.setValue(mon_maxnum[month.getValue()-1]);
128     }
129     public boolean checkInputValidity() {
130         if (year.isLeapYear()) {
131             if (year.validate()) {
132                 if (month.validate()) {
133                     if (mon_maxnum[month.getValue() - 1] == 31) {
134                         if (day.getValue() >= 1 && day.getValue() <= 31) return true;
135                         return false;
136                     }
137                     if (mon_maxnum[month.getValue() - 1] == 30) {
138                         if (day.getValue() >= 1 && day.getValue() <= 30) return true;
139                         return false;
140                     }
141                     if (mon_maxnum[month.getValue() - 1] + 1 == 29) {
142                         if (day.getValue() >= 1 && day.getValue() <= 29) return true;
143                         return false;
144                     }
145                 }
146                 return false;
147             }
148             return false;
149         } else {
150             if (year.validate()) {
151                 if (month.validate()) {
152                     if (mon_maxnum[month.getValue() - 1] == 31) {
153                         if (day.getValue() >= 1 && day.getValue() <= 31) return true;
154                         return false;
155                     }
156                     if (mon_maxnum[month.getValue() - 1] == 30) {
157                         if (day.getValue() >= 1 && day.getValue() <= 30) return true;
158                         return false;
159                     }
160                     if (mon_maxnum[month.getValue() - 1] == 28) {
161                         if (day.getValue() >= 1 && day.getValue() <= 28) return true;
162                         return false;
163                     }
164                 }
165                 return false;
166             }
167             return false;
168         }
169     }
170 
171     public DateUtil getNextNDays(int m) {
172         int i;
173         long sum = 0;
174         long sum1 = 0;
175         long sum2 = 0;
176         long sum3 = 0;
177         long sum4 = 0;
178         long n = (long) m;
179         DateUtil date1 = new DateUtil();
180         if (year.isLeapYear()) {
181             mon_maxnum[1] = 29;
182             for (i = 0; i < month.getValue() - 1; i++) {
183                 sum1 += mon_maxnum[i];
184             }
185             sum = sum1 + day.getValue();
186             i = 0;
187             if (sum + n <= 366) {
188                 while (sum2 + mon_maxnum[i] < sum + n) {
189                     sum2 += mon_maxnum[i];
190                     i++;
191                 }
192                 date1.year.setValue(year.getValue());
193                 date1.month.setValue(i + 1);
194                 date1.day.setValue((int) (sum + n - sum2));
195             } else {
196                 while (sum4 < sum + n) {
197                     if (year.isLeapYear()) {
198                         sum3 += 366;
199                         year.yearIncrement();
200                         if (year.isLeapYear()) {
201                             sum4 = sum3 + 366;
202                         } else sum4 = sum3 + 365;
203                         year.yearReduction();
204                     } else {
205                         sum3 += 365;
206                         year.yearIncrement();
207                         if (year.isLeapYear()) {
208                             sum4 = sum3 + 366;
209                         } else sum4 = sum3 + 365;
210                         year.yearReduction();
211                     }
212                     year.yearIncrement();
213                 }
214                 i = 0;
215                 sum2 = 0;
216                 if (year.isLeapYear()) mon_maxnum[1] = 29;
217                 else mon_maxnum[1] = 28;
218                 while ((sum2 + mon_maxnum[i]) < (sum + n - sum3)) {
219                     sum2 += mon_maxnum[i];
220                     i++;
221                 }
222                 date1.year.setValue(year.getValue());
223                 date1.month.setValue(i + 1);
224                 date1.day.setValue((int) (sum + n - sum3 - sum2));
225             }
226         } else {
227             for (i = 0; i < month.getValue() - 1; i++) {
228                 sum1 += mon_maxnum[i];
229             }
230             sum = sum1 + day.getValue();
231             i = 0;
232             if (sum + n <= 365) {
233                 while (sum2 + mon_maxnum[i] < sum + n) {
234                     sum2 += mon_maxnum[i];
235                     i++;
236                 }
237                 date1.year.setValue(year.getValue());
238                 date1.month.setValue(i + 1);
239                 date1.day.setValue((int) (sum + n - sum2));
240             } else {
241                 while (sum4 < sum + n) {
242                     if (year.isLeapYear()) {
243                         sum3 += 366;
244                         year.yearIncrement();
245                         if (year.isLeapYear()) {
246                             sum4 = sum3 + 366;
247                         } else sum4 = sum3 + 365;
248                         year.yearReduction();
249                     } else {
250                         sum3 += 365;
251                         year.yearIncrement();
252                         if (year.isLeapYear()) {
253                             sum4 = sum3 + 366;
254                         } else sum4 = sum3 + 365;
255                         year.yearReduction();
256                     }
257                     year.yearIncrement();
258                 }
259                 i = 0;
260                 sum2 = 0;
261                 if (year.isLeapYear()) mon_maxnum[1] = 29;
262                 else mon_maxnum[1] = 28;
263                 while ((sum2 + mon_maxnum[i]) < (sum + n - sum3)) {
264                     sum2 += mon_maxnum[i];
265                     i++;
266                 }
267                 date1.year.setValue(year.getValue());
268                 date1.month.setValue(i + 1);
269                 date1.day.setValue((int) (sum + n - sum3 - sum2));
270             }
271         }
272         return date1;
273     }
274 
275     public DateUtil getPreviousNDays(int m) {
276         int i;
277         long sum = 0;
278         long sum1 = 0;
279         long sum2 = 0;
280         long sum3 = 0;
281         long n = (long) m;
282         DateUtil date2 = new DateUtil();
283         if (year.isLeapYear())
284             mon_maxnum[1] = 29;
285         else mon_maxnum[1] = 28;
286             for (i = 0; i < month.getValue() - 1; i++) {
287                 sum1 += mon_maxnum[i];
288             }
289             sum = sum1 + day.getValue();
290             i = 0;
291             if (n < sum) {
292                 while ((sum2 + mon_maxnum[i]) < (sum - n)) {
293                     sum2 += mon_maxnum[i];
294                     i++;
295                 }
296                 date2.year.setValue(year.getValue());
297                 date2.month.setValue(i + 1);
298                 date2.day.setValue((int) (sum - n - sum2));
299             }
300             else {
301                 while (sum3 <= (n - sum)) {
302                    year.yearReduction();
303                     if (year.isLeapYear()) sum3 += 366;
304                     else sum3 += 365;
305                 }
306                 i = 0;
307                 sum2 = 0;
308                 if (year.isLeapYear()) mon_maxnum[1] = 29;
309                 else mon_maxnum[1] = 28;
310                 while ((sum2 + mon_maxnum[i]) < (sum3 - n + sum)) {
311                     sum2 += mon_maxnum[i];
312                     i++;
313                 }
314                 date2.year.setValue(year.getValue());
315                 date2.month.setValue(i + 1);
316                 date2.day.setValue((int) (sum3 - n + sum - sum2));
317             }
318             return date2;
319         }
320 
321     public int getDaysofDates(DateUtil date) {
322         int i, j, k;
323         int sum0 = 0;
324         int sum = 0;
325         int sum1 = 0;
326         int sum2 = 0;
327         int sum3 = 0;
328         int sum4 = 0;
329         if (year.isLeapYear())
330             mon_maxnum[1] = 29;
331         else mon_maxnum[1]=28;
332             for (i = 0; i < month.getValue() - 1; i++) {
333                 sum1 += mon_maxnum[i];
334             }
335             sum0 = sum1 + day.getValue();
336             if (date.getYear().isLeapYear()) date.mon_maxnum[1] = 29;
337             else date.mon_maxnum[1] = 28;
338             for (j = 0; j < date.getMonth().getValue() - 1; j++) {
339                 sum2 += date.mon_maxnum[j];
340             }
341             sum = sum2 + date.getDay().getValue();
342             if (equalTwoDates(date)) return 0;
343             else {
344                 Year year1 = new Year();
345                 if (compareDates(date)) {
346                     if (year.getValue() == date.getYear().getValue()) return (sum - sum0);
347                     else {
348                         for (k = (year.getValue() + 1); k < date.getYear().getValue(); k++) {
349                             year1.setValue(k);
350                             if (year1.isLeapYear()) sum3 += 366;
351                             else sum3 += 365;
352                         }
353                         if (year.isLeapYear()) return (sum3 + 366 - sum0 + sum);
354                         else return (sum3 + 365 - sum0 + sum);
355                     }
356                 } else {
357                     if (year.getValue() == date.year.getValue()) return (sum0 - sum);
358                     else {
359                         for (k = (date.getYear().getValue() + 1); k < year.getValue(); k++) {
360                             year1.setValue(k);
361                             if (year1.isLeapYear()) sum4 += 366;
362                             else sum4 += 365;
363                         }
364                         if (date.getYear().isLeapYear()) return (sum4 + 366 - sum + sum0);
365                         else return (sum4 + 365 - sum + sum0);
366                     }
367                 }
368             }
369         }
370 
371      public boolean compareDates(DateUtil date){
372             if(year.getValue()<date.getYear().getValue()) return true;
373             else if(year.getValue()==date.getYear().getValue()){
374                 if(month.getValue()<date.getMonth().getValue()) return true;
375                 else if(month.getValue()==date.getMonth().getValue()){
376                     if(day.getValue()<date.getDay().getValue()) return true;
377                     return false;
378                 }
379                 return false;
380             }
381             return false;
382         }
383         public boolean equalTwoDates(DateUtil date){
384             if(year.getValue()==date.getYear().getValue()&&month.getValue()==date.getMonth().getValue()&&day.getValue()==date.getDay().getValue()) return true;
385             else return false;
386         }
387 
388             public String showDate () {
389                 String s = year.getValue() + "-" + month.getValue() + "-" + day.getValue();
390                 return s;
391             }
392 }
393 class Day{
394     private int value;
395     Day(){
396 
397     }
398 
399     Day(int value){
400         this.value=value;
401     }
402 
403     int getValue(){
404         return value;
405     }
406 
407     void setValue(int value){
408         this.value=value;
409     }
410 
411     void dayIncrement(){
412         value+=1;
413     }
414 
415     void dayReduction(){
416         value-=1;
417     }
418 }
419 
420 class Month{
421     private int value;
422 
423     Month(){
424 
425     }
426 
427     Month(int Value){
428         value = Value;
429     }
430 
431     int getValue(){
432         return value;
433     }
434 
435     void setValue(int value){
436         this.value=value;
437     }
438 
439     void resetMin(){
440         value=1;
441     }
442 
443     void resetMax(){
444         value=12;
445     }
446 
447     boolean validate(){
448         if(value>=1&&value<=12){
449             return true;
450         }
451         else return false;
452     }
453 
454     void monthIncrement(){
455         value+=1;
456     }
457 
458     void monthReduction(){
459         value-=1;
460     }
461 }
462 
463 class Year{
464     private int value;
465 
466     Year(){
467 
468     }
469 
470     Year(int value){
471         this.value=value;
472     }
473 
474     int getValue(){
475         return value;
476     }
477 
478     void setValue(int value){
479         this.value=value;
480     }
481 
482     boolean isLeapYear(){
483         if((value%4==0&&value%100!=0)||(value%400==0)){
484             return true;
485         }
486         else return false;
487     }
488 
489     boolean validate(){
490         if(value>=1820&&value<=2020){
491             return true;
492         }
493         else return false;
494     }
495 
496     void yearIncrement(){
497         value+=1;
498     }
499 
500     void yearReduction(){
501         value-=1;
502     }
503 }
7-6 日期问题面向对象设计(聚合二)

类图:

解释与心得:

我做这题的思路是根据题目给出的类图来写题目,而且写完7-5来写这题就会十分的简单,这题的算法和逻辑和题目集3最后一题差不多,只是要求我们使用聚合来实现,而且这题的结构不一样,虽然说我这题看起来满分,但是类图跟题目给出的类图不一样,没有用到聚合,该聚合的关联,而且Main方法和其他几个类是依赖关系,本来主类只有和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 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 1 2
2 delete
2 delete
end
 

输出样例:

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

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

输入样例1:

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

麻婆豆腐 12
油淋生菜 9 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 4 2
end
 

输出样例1:

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

table 31: 
1 num out of range 16
2 portion out of range 4
table 31: 0 0
 

输入样例2:

桌号信息错误。例如:

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

输出样例2:

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

wrong format
 

输入样例3:

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

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

输出样例3:

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

wrong format
 

输入样例4:

错误的菜谱记录。例如:

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

输出样例4:

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

wrong format
table 55: 
invalid dish
麻婆豆腐 does not exist
2 油淋生菜 14
table 55: 14 10
 

输入样例5:

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

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

输出样例5:

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

wrong format
 

输入样例6:

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

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

输出样例6:

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

table 1: 
1 麻婆豆腐 12
2 油淋生菜 14
wrong format
record serial number sequence error
record serial number sequence error
table 1: 26 17
 

其他用例请参考公开的测试用例

代码长度限制
50 KB
时间限制
1000 ms
内存限制
64 MB

源码:

  1 import java.util.*;
  2 public class Main {
  3     public static void main(String[] args) {
  4         Scanner input = new Scanner(System.in);
  5         Menu menu = new Menu();
  6         Table[] tablemes = new Table[10];
  7         int dishAmount = 0;
  8         int orderAmount = 0;
  9         Dish dish;
 10         int tableAmount = 0;
 11         int count;
 12         String[] temp;
 13         int a1,a2,a3,a4,a5;
 14         int flag1=0;
 15         int mount=0;
 16         while (true) {
 17             String string = input.nextLine();
 18             temp = string.split(" ");
 19             if(string.equals("end"))
 20                 break;
 21             count = temp.length;
 22             if (count == 2) {
 23                 if (temp[1].equals("delete")) {
 24                     if(tablemes[tableAmount].getFlag()==1){
 25                     }
 26                     else{
 27                         a1 = Integer.parseInt(temp[0]);
 28                         if (tablemes[tableAmount].order.delARecordByOrderNum(a1) == 0) {
 29                             System.out.println("delete error;");
 30                         } else {
 31                             if (!tablemes[tableAmount].order.records[a1 - 1].IsDelete()) {
 32                                 int c = tablemes[tableAmount].order.delARecordByOrderNum(a1);
 33                                 tablemes[tableAmount].order.records[a1 - 1].setDelete(true);
 34                                 if(!tablemes[tableAmount].order.records[a1 - 1].d.IsSpecialDish()) tablemes[tableAmount].order.commonSum -= c;
 35                                 else tablemes[tableAmount].order.specialSum -= c;
 36                             } else System.out.println("deduplication " + a1);
 37                         }
 38                     }
 39                 } else {
 40                     if(flag1==1){
 41                         if(tablemes[tableAmount].getFlag()==1){
 42                         }
 43                         else System.out.println("invalid dish");
 44                     }
 45                     else{
 46                         if(temp[1].matches("[1-9][\\d]*")){
 47                             if(Integer.parseInt(temp[1])<300){
 48                                 a2 = Integer.parseInt(temp[1]);
 49                                 menu.dishs[dishAmount] = menu.addDish(temp[0], a2);
 50                                 dishAmount++;
 51                             }
 52                             else System.out.println(temp[0]+" price out of range "+temp[1]);
 53                         }
 54                         else if(temp[1].matches("0")) System.out.println(temp[0]+" price out of range "+temp[1]);
 55                         else System.out.println("wrong format");
 56                     }
 57                 }
 58             }
 59             else if(count==3){
 60                 if(temp[2].equals("T")){
 61                     if(temp[1].matches("[1-9][\\d]*")){
 62                         if(Integer.parseInt(temp[1])<300){
 63                             a2 = Integer.parseInt(temp[1]);
 64                             menu.dishs[dishAmount] = menu.addDish(temp[0], a2);
 65                             menu.dishs[dishAmount].setSpecialDish(true);
 66                             dishAmount++;
 67                         }
 68                         else System.out.println(temp[0]+" price out of range "+temp[1]);
 69                     }
 70                     else if(temp[1].matches("0")) System.out.println(temp[0]+" price out of range "+temp[1]);
 71                     else System.out.println("wrong format");
 72                 }
 73                 else System.out.println("wrong format");
 74             }
 75             else if (count == 4) {
 76                 if (temp[0].equals("table")) {
 77                     flag1=1;
 78                     if(temp[1].matches("[1-9][\\d]*")){
 79                         int num = Integer.parseInt(temp[1]);
 80                         if (num > 55) {
 81                             if(tableAmount==0)  tablemes[tableAmount] = new Table();
 82                             tablemes[tableAmount].setFlag(1);
 83                             System.out.println(num +" "+"table num out of range");
 84                         } else {
 85                             if(temp[2].matches("[1-9][\\d]{3}/[1-9][\\d]?/[1-9][\\d]?")){
 86                                 String[] str = temp[2].split("/");
 87                                 int year1=Integer.parseInt(str[0]);
 88                                 int month1=Integer.parseInt(str[1]);
 89                                 int day1=Integer.parseInt(str[2]);
 90                                 int[] mon_maxNum={0,31,28,31,30,31,30,31,31,30,31,30,31};
 91                                 if(month1>=1&&month1<=12){
 92                                     if(day1>=1&&day1<=mon_maxNum[month1]){
 93                                         if(year1>=2022&&year1<=2023){
 94                                             if(temp[3].matches("[1-9][\\d]?/[\\d]{2}/[\\d]{2}")){
 95                                                 tableAmount++;
 96                                                 orderAmount = 0;
 97                                                 mount=0;
 98                                                 tablemes[tableAmount] = new Table(temp[1], temp[2], temp[3]);
 99                                                 tablemes[tableAmount].setFlag(0);
100                                                 tablemes[tableAmount].processTime();
101                                                 tablemes[tableAmount].setCommonDiscount();
102                                                 tablemes[tableAmount].setSpecialDiscount();
103                                                 System.out.println("table " + temp[1] + ": ");
104                                             }
105                                             else{
106                                                 if(tableAmount==0)  tablemes[tableAmount] = new Table();
107                                                 tablemes[tableAmount].setFlag(1);
108                                                 System.out.println("wrong format");
109                                             }
110                                         }
111                                         else{
112                                             if(tableAmount==0)  tablemes[tableAmount] = new Table();
113                                             tablemes[tableAmount].setFlag(1);
114                                             System.out.println("not a valid time period");
115                                         }
116                                     }
117                                     else{
118                                         if(tableAmount==0)  tablemes[tableAmount] = new Table();
119                                         tablemes[tableAmount].setFlag(1);
120                                         System.out.println(num +" date error");
121                                     }
122                                 }
123                                 else{
124                                     if(tableAmount==0)  tablemes[tableAmount] = new Table();
125                                     tablemes[tableAmount].setFlag(1);
126                                     System.out.println(num +" date error");
127                                 }
128                             }
129                             else{
130                                 if(tableAmount==0)  tablemes[tableAmount] = new Table();
131                                 tablemes[tableAmount].setFlag(1);
132                                 System.out.println("wrong format");
133                             }
134                         }
135                     }
136                     else{
137                         if(tableAmount==0)  tablemes[tableAmount] = new Table();
138                         tablemes[tableAmount].setFlag(1);
139                         System.out.println("wrong format");
140                     }
141                 } else {
142                     if(tablemes[tableAmount].getFlag()==1){
143                     }
144                     else{
145                         a3 = Integer.parseInt(temp[0]);
146                         a4 = Integer.parseInt(temp[2]);
147                         a5 = Integer.parseInt(temp[3]);
148                         tablemes[tableAmount].order.addARecord(a3, temp[1],a4 , a5);
149                         dish = menu.searthDish(temp[1]);
150                         if(dish==null){
151                             System.out.println(temp[1]+" does not exist");
152                         }
153                         if (dish != null) {
154                             if(temp[2].matches("[1-3]")){
155                                 if(temp[3].matches("[1-9]")||temp[3].matches("1[0-5]")){
156                                     if(mount==0){
157                                         tablemes[tableAmount].order.records[orderAmount].setFlag2(1);
158                                         mount++;
159                                         tablemes[tableAmount].order.records[orderAmount].d = dish;
160                                         int a = tablemes[tableAmount].order.records[orderAmount].getPrice();
161                                         System.out.println(tablemes[tableAmount].order.records[orderAmount].orderNum + " " + dish.name + " " + a);
162                                         if(!dish.IsSpecialDish()) tablemes[tableAmount].order.commonSum += a;
163                                         else tablemes[tableAmount].order.specialSum += a;
164                                     }
165                                     else{
166                                         for(int i=orderAmount-1;i>=0;i--){
167                                             if(tablemes[tableAmount].order.records[i].flag2 ==1){
168                                                 if(a3<=tablemes[tableAmount].order.records[i].orderNum){
169                                                     System.out.println("record serial number sequence error");
170                                                 }
171                                                 else{
172                                                     tablemes[tableAmount].order.records[orderAmount].setFlag2(1);
173                                                     mount++;
174                                                     tablemes[tableAmount].order.records[orderAmount].d = dish;
175                                                     int a = tablemes[tableAmount].order.records[orderAmount].getPrice();
176                                                     System.out.println(tablemes[tableAmount].order.records[orderAmount].orderNum + " " + dish.name + " " + a);
177                                                     if(!dish.IsSpecialDish()) tablemes[tableAmount].order.commonSum += a;
178                                                     else tablemes[tableAmount].order.specialSum += a;
179                                                 }
180                                                 break;
181                                             }
182                                         }
183                                     }
184                                 }
185                                 else if(temp[2].matches("[1-9][\\d]*")) System.out.println(a3+" num out of range "+a5);
186                                 else System.out.println("wrong format");
187                             }
188                             else if(temp[2].matches("[4-9]")) System.out.println(a3+" portion out of range "+a4);
189                             else if(temp[2].matches("[1-9][\\d]*")) System.out.println("not a valid portion range");
190                             else System.out.println("wrong format");
191                         }
192                         orderAmount++;
193                     }
194                 }
195             }
196             else if (count == 5) {
197                 if(temp[0].matches("[1-9][\\d]*")){
198                     int num = Integer.parseInt(temp[0]);
199                     if (num > 55)  System.out.println("Table number :"+temp[0]+" does not exist");
200                     else {
201                         if(tablemes[tableAmount].getFlag()==1){
202                         }
203                         else{
204                             a1 = Integer.parseInt(temp[1]);
205                             a2 = Integer.parseInt(temp[3]);
206                             a3 = Integer.parseInt(temp[4]);
207                             tablemes[tableAmount].order.addARecord(a1, temp[2], a2, a3);
208                             dish = menu.searthDish(temp[2]);
209                             if (dish != null) {
210                                 tablemes[tableAmount].order.records[orderAmount].d = dish;
211                                 int b = tablemes[tableAmount].order.records[orderAmount].getPrice();
212                                 System.out.println(temp[1] + " table " + tablemes[tableAmount].tableNum + " pay for table " + temp[0] + " " + b);
213                                 if(!dish.IsSpecialDish()) tablemes[tableAmount].order.commonSum += b;
214                                 else tablemes[tableAmount].order.specialSum += b;
215                             }
216                             orderAmount++;
217                         }
218                     }
219                 }
220                 else System.out.println("wrong format");
221             }
222             else System.out.println("wrong format");
223         }
224         for (int i = 1; i < tableAmount + 1; i++) {
225             if(tablemes[i].getCommonDiscount()>0&&tablemes[i].getSpecialDiscount()>0){
226                 System.out.println("table " + tablemes[i].tableNum + ": "+tablemes[i].order.getTotalPrice()+" "+Math.round(tablemes[i].order.commonSum*tablemes[i].getCommonDiscount()+tablemes[i].order.specialSum*tablemes[i].getSpecialDiscount()));
227             }
228             else System.out.println("table " + tablemes[i].tableNum + " out of opening hours");
229         }
230     }
231 }
232 class Dish {
233     String name;
234     int unit_price;
235 
236     boolean isSpecialDish=false;
237 
238     public boolean IsSpecialDish() {
239         return isSpecialDish;
240     }
241 
242     public void setSpecialDish(boolean specialDish) {
243         isSpecialDish = specialDish;
244     }
245 
246     int getPrice(int portion) {
247         if (portion == 1) return unit_price;
248         else if (portion == 2) return Math.round((float) (unit_price * 1.5));
249         else return 2*unit_price;
250     }
251 }
252 class Menu {
253     Dish[] dishs = new Dish[10];
254     int dishCount = 0;
255     Dish searthDish(String dishName){
256         for(int i=dishCount-1;i>=0;i--){
257             if(dishName.equals(dishs[i].name)){
258                 return dishs[i];
259             }
260         }
261         return null;
262     }
263     Dish addDish(String dishName,int unit_price){
264         Dish dish = new Dish();
265         dish.name = dishName;
266         dish.unit_price = unit_price;
267         dishCount++;
268         return dish;
269     }
270 }
271 class Record {
272     int orderNum;
273     Dish d = new Dish();
274     int num = 0;
275     int portion;
276 
277     int flag2=0;
278 
279     public void setFlag2(int flag2) {
280         this.flag2 = flag2;
281     }
282 
283     boolean isDelete=false;
284     int getPrice(){
285         return d.getPrice(portion)*num;
286     }
287 
288     public void setDelete(boolean delete) {
289         isDelete = delete;
290     }
291     public boolean IsDelete() {
292         return isDelete;
293     }
294 
295 }
296 class Order {
297     Record[] records = new Record[10];
298     int count = 0;
299 
300     int commonSum;
301 
302     int specialSum;
303     void addARecord(int orderNum,String dishName,int portion,int num){
304         records[count] = new Record();
305         records[count].d.name = dishName;
306         records[count].orderNum = orderNum;
307         records[count].portion = portion;
308         records[count].num = num;
309         count++;
310     }
311     int getTotalPrice(){
312         return commonSum+specialSum;
313     }
314     int delARecordByOrderNum(int orderNum){
315         if(orderNum>count||orderNum<=0){
316             return 0;
317         }else {
318             return records[orderNum - 1].getPrice();
319         }
320     }
321     Record findRecordByNum(int orderNum) {
322         for (int i = count - 1; i >= 0; i--) {
323             if (orderNum == records[i].orderNum) {
324                 return records[i];
325             }
326         }
327         return null;
328     }
329 }
330 class Table {
331     int tableNum;
332     String Date;
333 
334     String tableTime;
335 
336     int flag=0;
337 
338     public int getFlag() {
339         return flag;
340     }
341 
342     public void setFlag(int flag) {
343         this.flag = flag;
344     }
345 
346     public Table() {
347     }
348 
349     public Table(String tableNum, String date, String tableTime) {
350         this.tableNum = Integer.parseInt(tableNum);
351         Date = date;
352         this.tableTime = tableTime;
353     }
354     int year,month,day,week,hh,mm,ss;
355     int sum=0;
356     Order order = new Order();
357     float commonDiscount = -1;
358 
359     float specialDiscount=-1;
360 
361     void processTime(){
362         String[] temp1 = Date.split("/");
363         String[] temp2 = tableTime.split("/");
364 
365         year = Integer.parseInt(temp1[0]);
366         month = Integer.parseInt(temp1[1]);
367         day = Integer.parseInt(temp1[2]);
368 
369         Calendar date = Calendar.getInstance();
370         date.set(year, (month-1), day);
371         week = date.get(Calendar.DAY_OF_WEEK);
372         if(week==1)
373             week = 7;
374         else
375             week--;
376         hh = Integer.parseInt(temp2[0]);
377         mm = Integer.parseInt(temp2[1]);
378         ss = Integer.parseInt(temp2[2]);
379 
380     }
381     void setCommonDiscount(){
382         if(week>=1&&week<=5)
383         {
384             if(hh>=17&&hh<20)
385                 commonDiscount =0.8F;
386             else if(hh==20&&mm<30)
387                 commonDiscount =0.8F;
388             else if(hh==20&&mm==30&&ss==0)
389                 commonDiscount =0.8F;
390             else if(hh>=11&&hh<=13||hh==10&&mm>=30)
391                 commonDiscount =0.6F;
392             else if(hh==14&&mm<30)
393                 commonDiscount =0.6F;
394             else if(hh==14&&mm==30&&ss==0)
395                 commonDiscount =0.6F;
396         }
397         else
398         {
399             if(hh>=10&&hh<=20)
400                 commonDiscount = 1.0F;
401             else if(hh==9&&mm>=30)
402                 commonDiscount = 1.0F;
403             else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
404                 commonDiscount = 1.0F;
405         }
406     }
407     void setSpecialDiscount(){
408         if(week>=1&&week<=5)
409         {
410             if(hh>=17&&hh<20)
411                 specialDiscount =0.7F;
412             else if(hh==20&&mm<30)
413                 specialDiscount =0.7F;
414             else if(hh==20&&mm==30&&ss==0)
415                 specialDiscount =0.7F;
416             else if(hh>=11&&hh<=13||hh==10&&mm>=30)
417                 specialDiscount =0.7F;
418             else if(hh==14&&mm<30)
419                 specialDiscount =0.7F;
420             else if(hh==14&&mm==30&&ss==0)
421                 specialDiscount =0.7F;
422         }
423         else
424         {
425             if(hh>=10&&hh<=20)
426                 specialDiscount = 1.0F;
427             else if(hh==9&&mm>=30)
428                 specialDiscount = 1.0F;
429             else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
430                 specialDiscount = 1.0F;
431         }
432     }
433 
434      float getCommonDiscount() {
435         return commonDiscount;
436     }
437 
438     float getSpecialDiscount() {
439         return specialDiscount;
440     }
441 }
7-1 菜单计价-4

类图:

报表内容:

解释与心得:

由于7-1 菜单计价-3没写,所以我是直接先写7-1 菜单计价-3再写这题,后面把两个题目的代码都优化了一下,也就是现在看到的代码。因为我前面说了我是怎么写7-1 菜单计价-3的,所以我就说我是怎么写这题吧,很明显这道题新加了很多异常情况,还有新功能,而且输入输出也改变了很多,而且做这题最需要注意的一个点就是当桌子的格式错误或者数据错误,直到下一个table出现,这个桌子下面的信息都不做处理,那么如何知道要不要对信息不做处理呢,我的做法是给桌子一个属性flag,在每次输入的字符串除了菜单和含有tabble的字符数组都判断一下flag,假如flag为0,那么,不处理,跳到下一个循环;假如flag为1,那么处理语句。新加了一个特色菜功能,Dish类应该新加一个属性isSpecialDish以及相关的getter和setter方法来判断该菜是不是特色菜,而且数组应该新加一个length是否为3的情况。当length为3时,判断完异常情况如果符合条件,再添加到菜单中,同时应该用方法setSpecialDish把isSpecialDish设为1。与上次不同的是当length为2时,总价格分两种,一种是特色菜的总价格,还有一种是普通菜的总价格。至于很多种情况,就需要看代码了,我讲的是思路。

(3)踩坑心得:

错误的代码:

改进后的代码:

心得:

经过我的查询,发现print和printf效率上存在一些差异。在 printf 的实现中,在调用 write 之前先写入 IO 缓冲区,这是一个用户空间的缓冲。系统调用是软中断,频繁调用,需要频繁陷入内核态,这样的效率不是很高,而 printf 实际是向用户空间的 IO 缓冲写,在满足条件的情况下才会调用 write 系统调用,减少 IO 次数,提高效率。而print则会关闭缓存区。

错误的代码:

改进的代码:

心得:一开始我觉得这两个代码并没有什么区别,但是仔细一想,应该是长度的差别,多了else,导致内存超限。

 

(4)改进建议:

学完正则表达式后,我觉得很多判断语句都可以用正则表达式来表达,可以提高效率。在写题目时,老是忘记老师讲的迪米特法则,也就是类之间的联系太紧密了。而且在写题目时,老是忘记给题目写注解,没有养成这样的习惯,导致后面写完题目在写注解就会十分浪费时间,而且不写注解就会降低代码的可读性。在写代码时,没有对属性进行封装,并且不会对相关的方法前面赋予public,而且很多时候代码格式没有依据JDK的格式。

(5) 总结:

经过这三次的题目集,我学会了正则表达式,以及如何对类之间进行聚合。以及这次的7-1 菜单计价-4锻炼了我的逻辑思维能力,以及加深了我对类的运用。这次的题目集7-3去掉重复的数据打破了我对循环的认知,让原本两层循环的做法,巧妙地变成了一层循环。而且通过这三次题目集,加深了我对数组和字符串的用法。而通过这次题目集,我认识到了自己的不足,需要对类和对象进行深入学习。至于意见方面,我对老师倒是没什么意见和建议,而是觉得自己不会主动去学习,主动去思考,而是等老师告诉我为什么、怎么做。