首页 > 其他分享 >BLOG-2

BLOG-2

时间:2023-11-16 20:22:27浏览次数:25  
标签:空格 记录 int BLOG 英文 菜品 new

一.前言

菜单四

菜单四是在菜单三的基础上迭代的,难度较大,因为要求有很多,这次大作业只要这一道题,但是也是要花费很长时间的

一些知识点:

  1. 类和对象:在代码中定义了几个类,如MenuItem(菜单项)、OrderItem(订单项)、TableOrder(桌子订单)和Table(桌子),它们用于组织和存储相关的数据和行为。

  2. 集合类的使用:使用ArrayList来存储菜单项、订单项和桌子订单等列表数据。通过添加、删除和遍历集合元素来管理订单信息。

  3. 条件语句和循环:使用if-else语句和for-each循环来处理不同的条件和迭代订单项。

  4. 方法的定义和调用:定义了一些方法来实现订单处理的逻辑,如添加订单项、删除订单项、计算菜品价格等。这些方法可以在需要的时候被调用。

  5. 字符串处理:使用String类的方法来比较字符串、转换大小写等。

  6. 数学运算:使用Math.round()函数对总价格进行四舍五入

菜单五

菜单计价程序-5也是在菜单三的基础上迭代的,还是很有难度的,但是经历了菜单四的折磨后,菜单五没有那么要命,但还是花了很多时间

一些知识点:

  1. 异常处理:通过try-catch语句块捕获并处理ParseException异常。

  2. 集合和数据结构:使用了ArrayListHashMap集合来存储菜单信息、订单信息以及其他数据。

  3. 字符串处理:使用了字符串的分割、拼接等操作,以及字符串的比较和匹配。

  4. 枚举类型(Enum):定义了一个DishType枚举类型来表示菜品类型。

  5. 自定义类和对象:定义了DishMenuRecordTable等类,并创建了相应的对象进行数据存储和操作。

  6. 时间和日期处理:使用了SimpleDateFormat类来解析和格式化日期和时间。

  7. 条件判断和逻辑运算:使用if-else语句对输入进行条件判断和处理。

  8. 数组操作:使用数组来存储字符串和数字等数据。

  9. 排序和比较:使用了Comparator接口和sort方法对字符串进行排序。

  10. 面向对象编程:代码中使用了面向对象的封装、继承、多态等概念,通过类和对象的组织和交互来实现功能。

期中考试

期中考试有四道题,层层递进的,不断迭代,题目难度还可以,比较容易吧

  1. 使用ArrayList存储Shape对象。
  2. 使用while循环根据用户选择创建不同类型的形状对象并添加到ArrayList中。
  3. 使用Comparator接口的naturalOrder()方法对列表进行排序。
  4. 实现Comparable接口来定义Shape对象之间的比较规则。
  5. 创建Point类来表示坐标点。
  6. 创建抽象类Shape,并在子类Circle和Rectangle中实现抽象方法

设计与分析:重点对题目的提交源码进行分析,可参考SourceMonitor的生成报表内容以及PowerDesigner的相应类图,要有相应的解释和心得(做到有图有真相),本次Blog主要分析PTA中的菜单计价系列的题目以及期中考试的三道题目

二.设计与分析

7-1 菜单计价程序-4

本体大部分内容与菜单计价程序-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+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价

代码如下:

  1 import java.util.*;
  2 public class Main {
  3     public static void main(String[] args) {
  4     try (Scanner in = new Scanner(System.in)) {
  5         String[] a=new String[50];
  6         int[]b=new int[50];
  7         Menu c=new Menu();
  8         table[] t=new table[50];
  9         Dish g=new Dish();
 10         int i=0;//桌号
 11         int j=0;//菜数
 12         int p=0;//当前处理桌号
 13         int lastdish=0;
 14         int dc1=0,dc2=0,dc3=0,dd1=0,dd2=0,dd3=0,dd4=0;
 15         int inputnum=0,h;
 16         a[0]=in.nextLine();
 17         b[0]=0;
 18         for (int i1 = 0; !a[inputnum].equals("end"); i1++){
 19             inputnum++;
 20             a[inputnum]=in.nextLine();
 21             b[inputnum]=0;
 22             switch (a[inputnum]) {
 23             case "":
 24                 System.out.println("wrong format");
 25                 inputnum--;
 26                 break;
 27             default:
 28                 // 其他情况的处理
 29                 break;
 30         }
 31 
 32         }
 33         Worn w=new Worn();
 34         w.worninput(a,inputnum,b);
 35         for(h=0;h<inputnum;h++)
 36         { 
 37             boolean flagerror=false;
 38             //分割字符
 39             String[] arr = a[h].split(" ");
 40             if(arr.length==4||arr[0].charAt(0)=='t')
 41             {
 42                 
 43                 if(arr[0].equals("table"))//加桌
 44                 {
 45                     flagerror=true;
 46                     lastdish=0;
 47                     table x=new table();
 48                     x.input(a[h],b[h]);
 49                     switch (i) {
 50                     case 0:
 51                         break;
 52                     default:
 53                         p = t[i - 1].searchtime(t, x, i);
 54                         break;
 55                     }
 56                         if(p==i)//加新桌
 57                         {
 58                             t[i]=new table();
 59                             t[p]=x;
 60                             i++;
 61                             lastdish=0;//初始化
 62                             while(t[p].flag) {
 63                                 System.out.println("table "+t[p].tablenum+": ");
 64                                 break;
 65                                 }
 66                         }    
 67                         else
 68                         {
 69                             while(t[p].flag) {
 70                                 System.out.println("table "+t[p].tablenum+": ");
 71                                 break;
 72                                 }
 73                             lastdish=0;
 74                         }
 75                         
 76                     }
 77                 else if(arr[0].matches("^[1-9][0-9]{0,1}$"))//自己点菜
 78                 {
 79                     if(b[h]==1)
 80                     {
 81                         flagerror=true;
 82                         while(i!=0&&t[p].flag)
 83                         {
 84                             System.out.println("wrong format");
 85                             break;
 86                         }
 87                         continue;
 88                     }
 89                     dc1=Integer.parseInt(arr[0]);
 90                     dc2=Integer.parseInt(arr[2]);
 91                     dc3=Integer.parseInt(arr[3]);
 92                     while(i!=0&&t[p].flag)
 93                     {
 94                             while(i!=0)
 95                             {                        
 96                                 if(dc1<=lastdish)
 97                                 {
 98                                     System.out.println("record serial number sequence error");
 99                                 }
100                                 else
101                                 {    
102                                     t[p].selforder.addARecord(0,dc1,arr[1],dc2,dc3,true);
103                                     g=c.searthDish(arr[1]);
104                                 
105                                     while(g!=null&&t[p].flag)
106                                     {
107                                         
108                                         if(dc2>3&&dc2<10||dc2<=0&&dc2>-10)//情况9
109                                         {
110                                             System.out.println(dc1+" portion out of range "+dc2);
111                                         }
112                                         else if(dc3>15)
113                                         {
114                                             System.out.println(dc1+" num out of range "+dc3);
115                                         }
116                                         else
117                                         {
118                                             t[p].selforder.records[t[p].k].d=g;
119                                             int x=t[p].selforder.records[t[p].k].getPrice();
120                                             lastdish=dc1;
121                                             System.out.println(dc1+" "+arr[1]+" "+x);
122                                         }
123                                         break;
124                                     }
125                                     t[p].k++;
126                             
127                         }
128                                 break;
129                     }
130                     break;
131                 }
132                 }
133                 else 
134                 {
135                     System.out.println("wrong format");
136                     flagerror=true;
137                 }
138                 
139             }
140         
141             else if(arr.length==5)//代点
142             {
143             //  1 4 麻婆豆腐 1 1
144                 if(b[h]==1)
145                 {
146                     flagerror=true;
147                     while(i!=0&&t[p].flag)
148                     {
149                         System.out.println("wrong format");
150                         break;
151                     }
152                     continue;
153                 }
154                 dd1=Integer.parseInt(arr[0]);
155                 dd2=Integer.parseInt(arr[1]);
156                 dd3=Integer.parseInt(arr[3]);
157                 dd4=Integer.parseInt(arr[4]);
158                 while(t[p].searthtable(t,dd1,p)==true)
159                 {
160                     t[p].selforder.addARecord(dd2, dd1, arr[2], dd3,dd4,false);
161                     g=c.searthDish(arr[2]);
162                     while(g!=null)
163                     {
164                         t[p].selforder.records[t[p].k].d=g;
165                         int x=t[p].selforder.records[t[p].k].getPrice();
166                         System.out.println(dd2+" table "+t[p].tablenum+" pay for table "+dd1+" "+x);
167                     break;
168                     }
169                     //k++;
170                     t[p].k++;
171                 break;
172                 }    
173             }
174             else if(arr.length==2)
175             {
176                 if(arr[1].equals("delete"))//删菜
177                 {
178                     
179                     if(i!=0)
180                     {
181                     if(b[h]==1)
182                     {
183                         flagerror=true;
184                         while(i!=0)
185                         {
186                             System.out.println("wrong format");
187                             break;
188                         }
189                         continue;
190                     }
191                     while(t[p].flag) {
192                         t[p].selforder.delARecordByOrderNum(Integer.parseInt(arr[0]),t[p]);
193                         break;
194                     }
195                     }
196                 }
197                 else//加菜
198                 {
199                     if(b[h]==1)
200                     {
201                         flagerror=true;
202                         System.out.println("wrong format");
203                         continue;
204                     }
205                     if(i!=0&&t[p].flag)//情况1
206                     {
207                         System.out.println("invalid dish");
208                     }
209                     else
210                     {
211                         if(Integer.parseInt(arr[1])>0&&Integer.parseInt(arr[1])<300)
212                         {
213                             c.addDish(arr[0], Integer.parseInt(arr[1]),false);
214                             j++;
215                         }
216                         else
217                         {
218                             System.out.println(arr[0]+" price out of range "+arr[1]);
219                         }
220                     }
221                 }
222             }
223             else if(arr.length==3)//特色菜
224             {
225                 if(b[h]==1)
226                 {
227                     flagerror=true;
228                     System.out.println("wrong format");
229                     continue;
230                 }
231                 if(i!=0&&t[p].flag)
232                 {
233                     System.out.println("invalid dish");
234                 }
235                 else 
236                 {
237                     while(arr[2].equals("T"))
238                     {
239                         if(Integer.parseInt(arr[1])>0&&Integer.parseInt(arr[1])<300)
240                         {
241                             c.addDish(arr[0], Integer.parseInt(arr[1]),true);
242                             j++;
243                         }
244                         else
245                         {
246                             System.out.println(arr[0]+" price out of range "+arr[1]);
247                         }
248                         break;
249                     }
250                 }
251             }     
252         }
253         int l = 0;
254         while (l < i) {
255             t[l].getTotalPrice();
256             l++;
257         }
258     } catch (NumberFormatException e) {
259         // TODO Auto-generated catch block
260         e.printStackTrace();
261     }
262     }
263 
264 }
265 class Dish
266 {
267     String name="";//菜品名称
268     int unit_price;
269     boolean special=false;//特色菜,true为是
270     //单价
271     int getPrice(int portion) {
272         int 菜价 = 0;
273         // 单菜价格
274         if (portion == 1) {
275             菜价 = unit_price;
276         } else if (portion == 2) {
277             菜价 = (int) Math.ceil(1.0 * unit_price * 3 / 2);
278         } else if (portion == 3) {
279             菜价 = unit_price * 2;
280         }
281         return 菜价;
282     }
283 
284 }
285 class Menu
286 {
287      Dish[] dishs =new Dish[20];
288      int i=0;//用于记录菜品总数
289      void addDish(String dishName,int unit_price,Boolean ts)
290      {
291          
292         // Dish dish1=new Dish();
293          dishs[i]=new Dish();
294          dishs[i].name=dishName;
295          dishs[i].unit_price=unit_price;
296          dishs[i].special=ts;
297          i++;
298          //return dish1;
299      }
300     //菜品数组,保存所有菜品信息
301     Dish searthDish(String dishName) //根据菜名在菜谱中查找菜品信息,返回Dish对象。
302     {
303         int j=0;
304         int flag=0;
305         j = i - 1;
306         while (j >= 0) {
307             if (dishName.compareTo(dishs[j].name) == 0) {
308                 flag = 1;
309                 break;
310             }
311             j--;
312         }
313         switch (flag) {
314         case 1:
315             return dishs[j];
316         default:
317             // 麻辣鸡丝 does not exist
318             System.out.println(dishName + " does not exist");
319             return null;
320     }
321 
322     }
323 }
324 class Record 
325 {
326     Dish d=new Dish();//菜品
327     int orderNum=0;//序号\
328     int portion=0;
329     int num=0;//份数
330     int tablenum=0;//桌号//没什么用
331     boolean self=true;
332     //份额(1/2/3代表小/中/大份)
333     int getPrice()
334     {
335         int n=0;
336         n=num*d.getPrice(portion);
337         //2 油淋生菜 27
338        // System.out.println(n);
339         return n;
340     }//计价,计算本条记录的价格
341 }
342 
343 class Order 
344 {
345     Record[] records=new Record[20];
346     int j=0;
347     int[] deletenum=new int[50];
348     //添加一条菜品信息到订单中。
349     void addARecord(int tablenum,int orderNum,String dishName,int portion,int num,boolean self)//添加一条菜品信息到订单中。
350     {
351         //1 麻婆豆腐 2 2
352         records[j]=new Record();
353         records[j].tablenum=tablenum;
354         records[j].orderNum=orderNum;
355         records[j].d.name=dishName;
356         records[j].portion=portion;
357         records[j].num=num;
358         records[j].self=self;
359         //System.out.println(num);
360         j++;
361     }
362 
363     boolean srarchdelete(int orderNum)//找到返回true
364     {
365         int i = 0;
366         while (i < 50) {
367             if (deletenum[i] != 0) {
368                 while (orderNum == deletenum[i]) {
369                     return true;
370                 }
371             } else {
372                 break;
373             }
374             i++;
375         }
376 
377         deletenum[i]=orderNum;
378         while(i==0)
379         {
380             return false;
381         }
382         return false;
383     }
384     void delARecordByOrderNum(int orderNum,table t)//根据序号删除一条记录
385     //试试直接总价减去删除菜
386     {
387         if(srarchdelete(orderNum)==false)
388         {
389             int i = 0;
390             while (i < j) {
391                 while (t.selforder.records[i].orderNum == orderNum) {
392                     t.selforder.records[i].num = 0;
393                     break;
394                 }
395                 // records[orderNum-1].getPrice();
396                 i++;
397             }
398 
399         }
400         else//情况4 
401         {
402             
403             System.out.println("deduplication "+orderNum);
404             
405         }
406     }
407     void srarchrecord(Record g,int k)
408     {
409         int i = 0;
410         while (i < k) {
411             if (g.d.name.equals(records[i].d.name) && g.portion == records[i].portion && records[i].self == true) {
412                 records[i].num += g.num;
413                 g.num = 0;
414                 break;
415             }
416             i++;
417         }
418 
419         
420     }
421 }
422 class table
423 {
424     int tablenum;//桌号
425     String time;//点菜时间//2023/3/22 12/2/3
426     int year=0,month=0,day=0,ww=0,hh=0,mm=0,ss=0; 
427     boolean flag=false;//判断时间是否正确
428     double count=0;//普通菜折扣
429     double specialcount=1;
430     Order selforder=new Order();//本桌订单
431     int sum=0;//计算总价
432     int truesum=0;//未打折价
433     int k=0;//点菜次数
434     int sumdish=0;//菜总数  
435     void input(String time,int b)//预处理
436     {
437         String[] arr1=time.split(" ");
438         int blank=0;
439                 for(int bk=0;bk<time.length();bk++)
440                 {
441                     while(time.charAt(bk)==' ')
442                     {
443                         blank++;
444                         break;
445                     }
446                 }
447         //桌号
448         if(blank!=3||!arr1[1].matches("^[1-9][0-9]{0,}$")||arr1.length!=4)
449         {
450              System.out.println("wrong format");
451         }
452         
453         //System.out.println();
454         else
455         {
456             this.time=arr1[2]+" "+arr1[3];
457            // System.out.println();
458             tablenum=Integer.parseInt(arr1[1]);
459             if(tablenum<=55&&tablenum>=1)
460             {
461                 if(this.time.matches("^([0-9]{4}/[0-9]{1,2}/[0-9]{1,2}) ([0-9]{1,2}/[0-9]{1,2}/[0-9]{1,2})$"))
462                 {
463                     if(arr1[2].matches("^(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})/((([0]{0,1}[13578]|1[02])/([0]{0,1}[1-9]|[12][0-9]|3[01]))|(([0]{0,1}[469]|11)/([0]{0,1}[1-9]|[12][0-9]|30))|([0]{0,1}2/([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})([48]|[0]{0,1}[2468][048]|[0]{0,1}[13579][26])|(([48]|[2468][048]|[3579][26])00))/[0]{0,1}2/29)$")&&arr1[3].matches("^([0-9]|([01][0-9])|(2[0-3]))/([0-9]|([0-5][0-9]))/([0-9]|([0-5][0-9]))$"))
464                     {
465                
466                         boolean flag1=judgetime1();
467                         if(flag1==true)//时间有效
468                         {
469                             timechange();
470                             jscount();
471                             pdflag();
472                             while(b==1) {
473                                 System.out.println("wrong format");
474                             break;    
475                             }
476                         }
477                         else
478                         {
479                             System.out.println("not a valid time period");
480                         }
481                     }
482                     else
483                     System.out.println(tablenum+" date error");
484                 }
485                 else
486                     System.out.println("wrong format");
487         
488             }
489             
490         
491             else
492              {
493                 System.out.println(arr1[1] +" table num out of range");
494              }
495     }
496     }
497 
498     boolean judgetime1()//是否有效//使用正则表达式
499     {
500         String[] arr=time.split(" ");
501         boolean flag=arr[0].matches("^(2022|2023)/(([13578]|0[13578]|10|12)/(([1-9]|0[1-9])|([12][0-9])|3[01])|([469]|0[469]|11)/(([1-9]|0[1-9])|([12][0-9])|30)|(2|02)/(([1-9]|0[1-9])|(1[0-9])|(2[0-8])))$");
502         boolean flag1=arr[1].matches("^([0-9]|([01][0-9])|(2[0-3]))/([0-9]|([0-5][0-9]))/([0-9]|([0-5][0-9]))$");
503         return (flag&&flag1);
504         
505     }
506     void getTotalPrice()//计算桌总价
507     {
508         if(flag)
509         {
510     
511             int j=selforder.j;
512             int i = j-1;
513             while(i>=0)
514             {
515                 selforder.srarchrecord(selforder.records[i],i);
516                 i--;
517             }
518             int i1 = 0;
519             while(i1<j)
520             {
521                 int x=0;
522                 x=selforder.records[i1].getPrice();
523                     truesum+=x;
524                 if(selforder.records[i1].d.special==true)//特色菜
525                 {
526                     sum+=(int)(x*specialcount+0.5);
527                 }
528                 else
529                     sum+=(int)(x*count+0.5);
530                 i1++;
531             }
532             
533             System.out.println("table "+tablenum+": "+truesum+" "+sum);
534             //table 1: 63
535         }
536         
537     }
538     void jscount()//运用时间计算折扣
539     {
540         if(ww>=1&&ww<=5)
541         {
542             specialcount=0.7;
543             switch (hh) {
544             case 17:
545             case 18:
546             case 19:
547                 count = 0.8;
548                 break;
549             case 20:
550                 if (mm < 30 || (mm == 30 && ss == 0)) {
551                     count = 0.8;
552                 }
553                 break;
554             case 11:
555             case 12:
556             case 13:
557                 count = 0.6;
558                 break;
559             case 10:
560                 if (mm >= 30) {
561                     count = 0.6;
562                 }
563                 break;
564             case 14:
565                 if (mm < 30 || (mm == 30 && ss == 0)) {
566                     count = 0.6;
567                 }
568                 break;
569         }
570 
571         }
572         else 
573         {
574             specialcount=1;
575             switch (hh) {
576             case 10:
577             case 11:
578             case 12:
579             case 13:
580             case 14:
581             case 15:
582             case 16:
583             case 17:
584             case 18:
585             case 19:
586             case 20:
587                 count = 1.0;
588                 break;
589             case 9:
590                 if (mm >= 30) {
591                     count = 1.0;
592                 }
593                 break;
594             case 21:
595                 if (mm < 30 || (mm == 30 && ss == 0)) {
596                     count = 1.0;
597                 }
598                 break;
599         }
600 
601         }
602     }
603     void pdflag()//判断时间是否正确
604     {
605          if(count==0)
606          {
607              System.out.println("table "+tablenum+" out of opening hours");
608              flag=false;
609          }
610          else
611              flag=true;
612 
613     }
614     void timechange()//时间转换
615     {
616         //2023/3/22 12/2/3
617          String[] arr=time.split(" ");
618          String[] arr1=arr[0].split("/");
619          String[] arr2=arr[1].split("/");
620          year=Integer.parseInt(arr1[0]);//时间
621          month=Integer.parseInt(arr1[1]);
622          day=Integer.parseInt(arr1[2]);
623          Calendar c = Calendar.getInstance();
624          c.set(year,month-1,day);//设置时间
625           ww=c.get(Calendar.DAY_OF_WEEK);
626           hh=Integer.parseInt(arr2[0]);//时间
627           mm=Integer.parseInt(arr2[1]);
628           ss=Integer.parseInt(arr2[2]);
629           switch (ww) {
630           case 1:
631               ww = 7;
632               break;
633           default:
634               ww--;
635               break;
636       }
637 
638     }
639     boolean searthtable(table[]t,int num,int p)
640     {
641         int i=0;
642         while(i<50)
643         {
644             if(t[i]!=null&&i!=p)
645             {
646                 while(t[i].tablenum==num&&t[i].flag) {
647                     return true;
648                 }
649             }
650             else
651                 break;
652             i++;
653         }
654         //"Table number :"+被点菜桌号+" does not exist"
655         System.out.println("Table number :"+num+" does not exist");
656         return  false;
657     }
658     int searchtime(table[]t,table a,int sumtable)//若找到返回对应桌,找不到返回下一个空桌
659     {
660         int i=0;
661         //(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)
662         while(i<sumtable)
663         {
664             while(a.tablenum==t[i].tablenum) {
665             while(a.year==t[i].year)
666             {
667                 while(a.day==t[i].day)
668                 {
669                     if(a.ww>=1&&a.ww<=5)//周1~5
670                     {
671                         while(a.hh<=14&&t[i].hh<=14||a.hh>14&&t[i].hh>14)//在同一时段
672                         {
673                             
674                             return i;
675                             
676                         }
677                     }
678                     else//周末
679                     {
680                         while(Math.abs((a.hh-t[i].hh)*60*60+(a.mm-t[i].mm)*60)+(a.ss-t[i].ss)<60*60)//在同一时段
681                         {
682                             
683                             return i;
684                         }
685                         
686                     }
687                     break;
688                 }
689                 break;
690             }
691             break;
692             }
693             i++;
694         }
695         //System.out.println(sumtable);
696         return sumtable;
697     }
698 
699 }
700 class Worn//错误判断,错误b[i]==1
701 {
702     void worninput(String[]a,int num,int[]b) 
703     {
704         //boolean flag1=true;
705         int i=0;
706         while(i<num)
707         {
708             String[] arr=a[i].split(" ");
709             boolean flag=false;
710             //麻婆豆腐 12
711             while(arr.length>5)
712             {
713                 b[i]=1;
714                 break;
715             }
716             if(a[i].matches("^[\u4e00-\u9fa5]{1,} ([1-9][0-9]{0,2})$")==true)//普通菜存入
717             {    
718                 flag=true;
719             }
720             //油淋生菜 9 T
721             else if(a[i].matches("^[\u4e00-\u9fa5]{1,4} ([1-9][0-9]{0,2}) [T]$")==true)//特色菜存入
722             {
723                 flag=true;
724             }
725             //table 31 2023/2/1 14/20/00
726             else if(arr[0].equals("table")==true)//桌
727             {
728                 int blank=0;
729                 int bk=0;
730                 while(bk<a[i].length())
731                 {
732                     while(a[i].charAt(bk)==' ')
733                     {
734                         blank++;
735                         break;
736                     }
737                     bk++;
738                 }
739                 while(arr[1].matches("^([1-9][0-9]{0,})$")&&blank==3) {
740                 flag=true;
741                 break;
742                 }
743                 //int blank=0;
744                 
745             }
746             //1 麻婆豆腐 1 16
747             else if(a[i].matches("^[1-9][0-9]{0,2} [\u4e00-\u9fa5]{1,} [1-9] ([1-9][0-9]{0,1})$")==true)//自己点菜
748             {
749                 flag=true;
750             }
751             //1 1 麻婆豆腐 1 16
752             else if(a[i].matches("^([1-9][0-9]{0,1}) [1-9][0-9]{0,2} [\u4e00-\u9fa5]{1,} [1-9] ([1-9][0-9]{0,1})$")==true)//待点菜
753             {
754                 flag=true;
755             }
756             //2 delete
757             else if(a[i].matches("^([1-9][0-9]{0,1}) delete$")==true)//删菜
758             {
759                 flag=true;
760             }
761             else if(a[i].matches("^end$")==true)//结尾
762             {
763                 flag=true;
764             }
765             while(flag==false)
766             {
767                 b[i]=1;
768                 break;
769             }
770             i++;
771         }
772     }
773 }

类图如下:

 代码难易程度如下图所示:

分析:

  1. Dish 类:表示菜品,包含菜名、单价、是否为特色菜等信息。getPrice 方法用于计算菜品的价格。

  2. Menu 类:表示菜单,包含菜品数组和添加菜品的方法。searthDish 方法用于根据菜名查找菜品。

  3. Record 类:表示订单中的一条记录,包含菜品、序号、份额、份数等信息。getPrice 方法用于计算记录的价格。

  4. Order 类:表示订单,包含记录数组和添加记录的方法。srarchdelete 方法用于在订单中查找是否存在相同的记录,delARecordByOrderNum 方法用于根据序号删除记录。

  5. table 类:表示桌子订单,包含桌号、时间、订单等信息。getTotalPrice 方法用于计算桌子订单的总价,jscount 方法用于根据时间计算折扣。

  6. Worn 类:用于检查输入是否符合预期格式,主要通过正则表达式进行判断。

  7. Main 类:包含 main 方法,用于程序的入口。通过命令行输入,处理用户输入的各种操作,包括添加桌子、点菜、代点菜、加菜、删菜等。

7-1 菜单计价程序-5

本题在菜单计价程序-3的基础上增加了部分内容,增加的内容用加粗字体标识。

注意不是菜单计价程序-4,本题和菜单计价程序-4同属菜单计价程序-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)//根据序号查找一条记录

 

}

 

### 输入格式:

 

桌号标识格式: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+英文空格+桌号+“:”+英文空格+当前桌的总价

 

以上为菜单计价系列-3的题目要求,加粗的部分是有调整的内容。本次课题相比菜单计价系列-3新增要求如下:

 

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

例如:麻婆豆腐 川菜 9 T

菜价的计算方法:

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

特色菜的口味类型:川菜、晋菜、浙菜

川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣;

晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸;

浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜;    

例如:麻婆豆腐 川菜 9 T

输入订单记录时如果是特色菜,添加口味度(辣/酸/甜度)值,格式为:序号+英文空格+菜名+英文空格+口味度值+英文空格+份额+英文空格+份数

例如:1 麻婆豆腐 4 1 9

单条信息在处理时,如果口味度超过正常范围,输出"spicy/acidity/sweetness num out of range : "+口味度值,spicy/acidity/sweetness(辣度/酸度/甜度)根据菜品类型择一输出,例如:

acidity num out of range : 5

输出一桌的信息时,按辣、酸、甜度的顺序依次输出本桌菜各种口味的口味度水平,如果没有某个类型的菜,对应的口味(辣/酸/甜)度不输出,只输出已点的菜的口味度。口味度水平由口味度平均值确定,口味度平均值只综合对应口味菜系的菜计算,不做所有菜的平均。比如,某桌菜点了3份川菜,辣度分别是1、3、5;还有4份晋菜,酸度分别是,1、1、2、2,辣度平均值为3、酸度平均值四舍五入为2,甜度没有,不输出。

一桌信息的输出格式:table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格+"川菜"+数量+辣度+英文空格+"晋菜"+数量+酸度+英文空格+"浙菜"+数量+甜度。

如果整桌菜没有特色菜,则只输出table的基本信息,格式如下,注意最后加一个英文空格:

table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格

例如:table 1: 60 36 川菜 2 爆辣 浙菜 1 微甜

计算口味度时要累计本桌各类菜系所有记录的口味度总和(每条记录的口味度乘以菜的份数),再除以对应菜系菜的总份数,最后四舍五入。

注:本题要考虑代点菜的情况,当前桌点的菜要加上被其他桌代点的菜综合计算口味度平均值。

 

 

2、考虑客户订多桌菜的情况,输入时桌号时,增加用户的信息:

格式:table+英文空格+桌号+英文空格+":"+英文空格+客户姓名+英文空格+手机号+日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

例如:table 1 : tom 13670008181 2023/5/1 21/30/00

约束条件:客户姓名不超过10个字符,手机号11位,前三位必须是180、181、189、133、135、136其中之一。

输出结果时,先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。不考虑各桌时间段的问题,同一个客户的所有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+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格

 

最后按拼音顺序输出每位客户(不考虑客户同名或拼音相同的情况)的支付金额,格式: 用户姓名+英文空格+手机号+英文空格+支付总金额,按输入顺序排列。

代码如下:

  1 import java.io.BufferedReader;
  2 import java.io.IOException;
  3 import java.io.InputStreamReader;
  4 import java.time.LocalDate;
  5 import java.util.ArrayList;
  6 import java.time.format.DateTimeFormatter;
  7 import java.util.Arrays;
  8 import java.util.regex.Pattern;
  9 import java.util.regex.Matcher;
 10 import java.time.*;
 11 import java.time.DayOfWeek;
 12 public class Main {
 13     public static void main(String[] args) throws IOException {
 14         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
 15         Dish[] dishes = new Dish[20];
 16         SpecialDish[] specialDishes = new SpecialDish[20];
 17         Table table = new Table();
 18         Record[] records = new Record[20];
 19         PersonPay[] personPays = new PersonPay[10];
 20         Order order = new Order();
 21         Menu menu = new Menu();
 22         caicage cage = new caicage() ;
 23         lastPrint print = new lastPrint();
 24         inputmat mat = new inputmat() ;
 25         ArrayList<Table> tables = new ArrayList<>();
 26         int x = 0 , y = 0 , z = 0 , z1 = 0 , p = 0 ;
 27         String menuName , name , tableName , telephoneNum , taste;
 28         int tableNum , dishNum , portion , num , unit_price , deleteNum , tasteNum;
 29         boolean isHaveTable = false , forOther = false;
 30         boolean  falg = true;
 31         while(falg){
 32             String input = in.readLine();
 33             if(input.equals("end")){
 34                 if(x!=0){
 35                     table.order = order;
 36                     tables.add(x-1 , table);
 37                 }
 38 
 39                 break;
 40             }
 41             String[] getInput = input.split(" ");
 42             int flag = mat.inpumat(input);
 43             switch(flag) {
 44             case 1: {
 45                 if (x != 0) {
 46                     table.order = order;
 47                     tables.add(x - 1, table);
 48                     table = new Table();
 49                     y = 0;
 50                 }
 51                 isHaveTable = true;
 52                 tableNum = Integer.parseInt(getInput[1]);
 53                 tableName = getInput[3];
 54                 telephoneNum = getInput[4];
 55                 String dayTime = getInput[5];
 56                 String hourTime = getInput[6];
 57 
 58                 table.tableNum = tableNum;
 59                 table.tableName = tableName;
 60                 table.telephoneNum = telephoneNum;
 61                 table.mainTime = dayTime;
 62                 table.remainTime = hourTime;
 63 
 64                 if (!table.timeJudgement1()) {
 65                     isHaveTable = false;
 66                     System.out.println("table " + table.tableNum + " out of opening hours");
 67                     continue;
 68                 }
 69 
 70                 order = new Order();
 71                 records = new Record[10];
 72 
 73                 if (x == 0) {
 74                     personPays[p] = new PersonPay();   //人名
 75                     personPays[p].name = tableName;
 76                     personPays[p].telephoneNum = telephoneNum;  //电话号码
 77                     p++;
 78                     print.p = p;   //应该输出多少次
 79                 } else {
 80                     boolean isNewPerson = true;
 81                     for (int i = 0; i < p; i++) {
 82                         if (personPays[i].name.equals(tableName) && personPays[i].telephoneNum.equals(telephoneNum)) {
 83                             isNewPerson = false;
 84                             break;
 85                         }
 86                     }
 87                     if (isNewPerson) {
 88                         personPays[p] = new PersonPay();
 89                         personPays[p].name = tableName;
 90                         personPays[p].telephoneNum = telephoneNum;
 91                         p++;
 92                         print.p = p;
 93                     }
 94                 }
 95 
 96                 System.out.println("table " + tableNum + ": ");
 97                 x++;
 98                 break;
 99             }
100 
101             case 2: {//普通菜单
102                 menuName = getInput[0];
103                 unit_price = Integer.parseInt(getInput[1]);
104                 
105                 boolean dishFound = false;
106                 for (int i = 0; i < z; i++) {
107                     if (menuName.equalsIgnoreCase(dishes[i].name)) {
108                         dishes[i].unit_price = unit_price;
109                         dishFound = true;
110                         break;
111                     }
112                 }
113 
114                 if (!dishFound) {
115                     dishes[z] = menu.addDish(menuName, unit_price);
116                     z++;
117                 }
118 
119                 menu.dishes = dishes;
120                 menu.dishNum = z;
121                 break;
122             }
123 
124             case 3: { //特色菜
125                 menuName = getInput[0];
126                 unit_price = Integer.parseInt(getInput[2]);
127                 String tasteToAdd = getInput[1]; // 修改变量名为tasteToAdd
128 
129                 boolean specialDishFound = false;
130                 int i;
131                 for (i = 0; i < z1; i++) {
132                     if (menuName.equalsIgnoreCase(specialDishes[i].name)) {
133                         specialDishes[i].unit_price = unit_price;
134                         specialDishFound = true;
135                         break;
136                     }
137                 }
138 
139                 if (!specialDishFound) {
140                     specialDishes[z1] = menu.addSpecialDish(menuName, unit_price, tasteToAdd);
141                     z1++;
142                 }
143 
144                 menu.specialDishes = specialDishes;
145                 menu.dishNum1 = z1;
146                 break;
147             }
148 
149                 case 4: {
150                     if (!isHaveTable)
151                         continue;
152                     name = getInput[1];
153                     if (menu.searthDish(name) != null) {
154                         dishNum = Integer.parseInt(getInput[0]);
155                         portion = Integer.parseInt(getInput[2]);
156                         num = Integer.parseInt(getInput[3]);
157                         records[y] = new Record();
158                         records[y] = order.addARecord(dishNum, name, portion, num, menu);
159                         records[y].isSpecialDish = false;
160                         System.out.println(records[y].orderNum + " " + records[y].d.name + " " + records[y].getPrice());
161                         y++;
162                         order.records = records;
163                         order.dishNum = y;
164                     } else {
165                         System.out.println(name + " does not exist");
166                     }
167                     break;
168                 }
169               
170                 case 5: {
171                     if (!isHaveTable)
172                         continue;
173                     name = getInput[1];
174                     SpecialDish specialDish = menu.searthSpecialDish(name);
175                     if (specialDish != null) {
176                         tasteNum = Integer.parseInt(getInput[2]);
177                         num = Integer.parseInt(getInput[4]);
178                         int flag1 = mat.findcage(specialDish.taste);
179                         if ((flag1 == 1 && tasteNum >= 0 && tasteNum <= 5)
180                                 || (flag1 == 2 && tasteNum >= 0 && tasteNum <= 4)
181                                 || (flag1 == 3 && tasteNum >= 0 && tasteNum <= 3)) {
182                             records[y] = order.addASpecialRecord(Integer.parseInt(getInput[0]), name, Integer.parseInt(getInput[3]), num, menu, tasteNum, forOther);
183                             records[y].isSpecialDish = true;
184                             System.out.println(records[y].orderNum + " " + records[y].d.name + " " + records[y].getPrice());
185                             y++;
186                             order.records = records;
187                             order.dishNum = y;
188                         } else {
189                             mat.error(tasteNum, flag1);
190                             break;
191                         }
192                     } else {
193                         System.out.println(name + " does not exist");
194                         continue;
195                     }
196                     break;
197                 }
198 
199                 case 6: {
200                     if (!isHaveTable)
201                         continue;
202                     deleteNum = Integer.parseInt(getInput[0]);
203                     if (order.findRecordByNum(deleteNum) == 1) {
204                         order.delARecordByOrderNum(deleteNum);
205                     } else
206                         System.out.println("delete error;");
207                     break;
208                 }
209                 case 7: {
210                     int t = Integer.parseInt(getInput[0]);
211                     name = getInput[2];
212                     for (int i = 0; i < x - 1; i++) {
213                         if (tables.get(i).tableNum == t && menu.searthDish(name) != null) {
214                             records[y] = order.addARecord(Integer.parseInt(getInput[1]), name, Integer.parseInt(getInput[3]), Integer.parseInt(getInput[4]), menu);
215                             records[y].isSpecialDish = false;
216                             System.out.println(getInput[1] + " table " + table.tableNum + " pay for table " + t + " " + records[y].getPrice());
217                             y++;
218                             order.records = records;
219                             order.dishNum = y;
220                             break;
221                         }
222                     }
223                     break;
224                 }
225 
226                 case 8: {
227                     int t = Integer.parseInt(getInput[0]);
228                     name = getInput[2];
229                     tasteNum = Integer.parseInt(getInput[3]);
230                     int flag1 = mat.findcage(menu.searthSpecialDish(name).taste);
231                     for (int i = 0; i < x - 1; i++) {
232                         if (tables.get(i).tableNum == t && menu.searthSpecialDish(name) != null) {
233                             if (((flag1 == 1 && tasteNum >= 1 && tasteNum <= 5) ||
234                                     (flag1 == 2 && tasteNum <= 4) ||
235                                     (flag1 == 3 && tasteNum <= 3))) {
236                                 records[y] = new Record();
237                                 dishNum = Integer.parseInt(getInput[1]);
238                                 portion = Integer.parseInt(getInput[4]);
239                                 num = Integer.parseInt(getInput[5]);
240                                 records[y] = order.addASpecialRecord(dishNum, name, portion, num, menu, tasteNum, !forOther);
241                                 records[y].isSpecialDish = true;
242                                 System.out.println(dishNum + " table " + table.tableNum + " pay for table " + t + " " + records[y].getPrice());
243                                 tables.get(i).giveTaste(name, num, tasteNum, menu);
244                                 y++;
245                                 order.records = records;
246                                 order.dishNum = y;
247                             }
248                             break;
249                         }
250                     }
251                     break;
252                 }
253 
254                 default :{
255                     System.out.println("wrong format");
256                     break;
257                 }
258             }
259         }
260         print.tables = tables;
261         print.personPays = personPays;
262         for (Table table1 : tables) {
263             table1.order.getTotalPrice();
264             table1.getTaste();
265             if(table1.spicyNum==0&&table1.acidityNum==0&&table1.sweetnessNum==0)
266                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice()+" ");
267             if(table1.spicyNum!=0&&table1.acidityNum==0&&table1.sweetnessNum==0)
268                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice() + " 川菜 " +(int)table1.spicyNum+" "+mat.spicyLevel(table1.averageSpicy ));
269             if(table1.spicyNum==0&&table1.acidityNum!=0&&table1.sweetnessNum==0)
270                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice() + " 晋菜 " +(int)table1.acidityNum+" "+mat.acidityLevel(table1.averageAcidity ));
271             if(table1.spicyNum==0&&table1.acidityNum==0&&table1.sweetnessNum!=0)
272                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice() + " 浙菜 " +(int)table1.sweetnessNum+" "+ mat.sweetnessLevel(table1.averageSweetness ));
273             if(table1.spicyNum!=0&&table1.acidityNum!=0&&table1.sweetnessNum==0)
274                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice() + " 川菜 " +(int)table1.spicyNum+" "+mat.spicyLevel(table1.averageSpicy )+" 晋菜 "+(int)table1.acidityNum+" "+mat.acidityLevel(table1.averageAcidity ) );
275             if(table1.spicyNum!=0&&table1.acidityNum==0&&table1.sweetnessNum!=0)
276                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice() + " 川菜 " +(int)table1.spicyNum+" "+mat.spicyLevel(table1.averageSpicy )+" 浙菜 "+(int)table1.sweetnessNum+" "+mat.sweetnessLevel(table1.averageSweetness ) );
277             if(table1.spicyNum==0&&table1.acidityNum!=0&&table1.sweetnessNum!=0)
278                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice() + " 晋菜 " +(int)table1.acidityNum+" "+mat.acidityLevel(table1.averageAcidity ) +" 浙菜 "+(int)table1.sweetnessNum+" "+mat.sweetnessLevel(table1.averageSweetness ));
279             if(table1.spicyNum!=0&&table1.acidityNum!=0&&table1.sweetnessNum!=0)
280                 System.out.println("table " + table1.tableNum + ": " + (table1.order.allCommonPrice + table1.order.allSpecialPrice) + " " + table1.tablePrice() + " 川菜 " +(int)table1.spicyNum+" "+mat.spicyLevel(table1.averageSpicy )+" 晋菜 "+(int)table1.acidityNum+" "+mat.acidityLevel(table1.averageAcidity ) +" 浙菜 "+(int)table1.sweetnessNum+" "+mat.sweetnessLevel(table1.averageSweetness ));
281         }
282         print.payPrint();
283     }
284 }
285 class Dish{
286     String name;
287     String taste;
288     int unit_price;
289     public int getPrice(int portion){
290         int Price=0;
291         if(portion==1)
292             Price=unit_price;
293         else if(portion==3)
294             Price=unit_price*2;
295         else if(portion==2)
296             Price=(int)Math.round((float)unit_price*1.5);
297         return Price;
298     }
299 }
300 class SpecialDish extends Dish{
301 }
302 class Menu{
303     Dish[] dishes;
304     SpecialDish[] specialDishes;
305     int dishNum;
306     int dishNum1;
307    
308     public Dish searthDish(String dishName){
309         for(int k=0;k<dishNum;k++) {
310             if(dishName.equals(dishes[k].name)){
311                 return dishes[k];
312             }
313         }
314         return null;
315     }
316     public SpecialDish searthSpecialDish(String dishName){
317         for(int k=0;k<dishNum1;k++) {
318             if(dishName.equals(specialDishes[k].name)){
319                 return specialDishes[k];
320             }
321         }
322         return null;
323     }
324     public Dish addDish(String dishName,int unit_price){
325         Dish addDish=new Dish();
326         addDish.name=dishName;
327         addDish.unit_price=unit_price;
328         return addDish;
329     }
330     public SpecialDish addSpecialDish(String dishName,int unit_price,String taste){
331         SpecialDish addDish=new SpecialDish();
332         addDish.name=dishName;
333         addDish.unit_price=unit_price;
334         addDish.taste=taste;
335         return addDish;
336     }
337 }
338  class usedClass {
339  
340 }
341 
342 class Record{
343     int orderNum;
344     Dish d;
345     int portion;
346     int num;
347     int spicy;
348     int acidity;
349     int sweetness;
350     boolean isSpecialDish;
351     public int getPrice() {
352         return d.getPrice(portion)*num;
353     }
354 }
355 class Order {
356     int dishNum;
357     int allCommonPrice;
358     int allSpecialPrice;
359     Record[] records = new Record[30];
360 
361     public void getTotalPrice(){
362         for(int k=0;k<dishNum;k++) {
363             if(!records[k].isSpecialDish)
364                 allCommonPrice+=records[k].getPrice();
365             else
366                 allSpecialPrice+=records[k].getPrice();
367         }
368     }
369 
370     public int getTotalPrice(double commonDiscount,double specialDiscount){
371         int totalPrice = 0;
372         for(int k=0;k<dishNum;k++) {
373             totalPrice += records[k].isSpecialDish ? Math.round(records[k].getPrice()*specialDiscount) : Math.round(records[k].getPrice()*commonDiscount);
374         }
375         return totalPrice;
376     }
377 
378     public Record addARecord(int orderNum,String dishName,int portion,int num , Menu menu){
379         Record order=new Record();
380         order.d=menu.searthDish(dishName);
381         order.orderNum=orderNum;
382         order.portion=portion;
383         order.num=num;
384         return order;
385     }
386 
387    public Record addASpecialRecord(int orderNum, String dishName, int portion, int num, Menu menu, int tasteNum, boolean forOther) {
388     Record order = new Record();
389     order.d = menu.searthSpecialDish(dishName);
390     order.orderNum = orderNum;
391     order.portion = portion;
392     order.num = num;
393 
394     if (!forOther) {
395         inputmat mt = new inputmat();
396         int flag = mt.findcage(menu.searthSpecialDish(dishName).taste);
397         if (flag == 1) {
398             order.spicy = tasteNum;
399             order.acidity = -1;
400             order.sweetness = -1;
401         } else if (flag == 3) {
402             order.spicy = -1;
403             order.acidity = -1;
404             order.sweetness = tasteNum;
405         } else if (flag == 2) {
406             order.spicy = -1;
407             order.acidity = tasteNum;
408             order.sweetness = -1;
409         }
410     } else {
411         order.spicy = -1;
412         order.acidity = -1;
413         order.sweetness = -1;
414     }
415 
416     return order;
417 }
418 
419     public void delARecordByOrderNum(int orderNum){
420         for(int k=0;k<dishNum;k++) {
421             if(orderNum==records[k].orderNum) {
422                 records[k].num=0;
423             }
424         }
425     }
426 
427     public int findRecordByNum(int orderNum){
428         for(int k = 0; k<dishNum;k++) {
429             if(records[k].orderNum==orderNum) {
430                 return 1;
431             }
432         }
433         return 0;
434     }
435 }
436 
437 class Table {
438     int tableNum;
439     String tableName;
440     String telephoneNum;
441     String mainTime;
442     String remainTime;
443     Order order;
444     double commonDiscount;
445     double specialDiscount;
446     int averageSpicy;
447     int averageAcidity;
448     int averageSweetness;
449     double spicyNum;
450     double acidityNum;
451     double sweetnessNum;
452     int week;
453 
454     public boolean timeJudgement1() {
455     String[] timeArray = remainTime.split("/");
456     String[] dateArray = mainTime.split("/");
457     int time = Integer.parseInt(timeArray[0]) * 10000 + Integer.parseInt(timeArray[1]) * 100 + Integer.parseInt(timeArray[2]);
458     week = new inputmat().datetime(mainTime);
459 
460     if ((week == 6 || week == 7) && (time >= 93000 && time <= 213000)) {
461         specialDiscount = commonDiscount = 1;
462         return true;
463     } else if (week >= 1 && week <= 5) {
464         if (time >= 103000 && time <= 143000) {
465             setDiscounts(0.6, 0.7);
466             return true;
467         } else if (time >= 170000 && time <= 203000) {
468             setDiscounts(0.8, 0.7);
469             return true;
470         }
471     }
472     return false;
473 }
474 
475 private void setDiscounts(double common, double special) {
476     commonDiscount = common;
477     specialDiscount = special;
478 }
479 
480     public int tablePrice() {
481         return order.getTotalPrice(commonDiscount, specialDiscount);
482     }
483 
484     public void getTaste() {
485         for (int k = 0; k < order.dishNum; k++) {
486             if (order.records[k].isSpecialDish) {
487                 Record record = order.records[k];
488                 updateTasteAverages(record.acidity, record.spicy, record.sweetness, record.num);
489             }
490         }
491         calculateAverageTaste();
492     }
493 
494     private void updateTasteAverages(int acidity, int spicy, int sweetness, int num) {
495         if (acidity != -1) {
496             averageAcidity += acidity * num;
497             acidityNum += num;
498         }
499         if (spicy != -1) {
500             averageSpicy += spicy * num;
501             spicyNum += num;
502         }
503         if (sweetness != -1) {
504             averageSweetness += sweetness * num;
505             sweetnessNum += num;
506         }
507     }
508 
509     private void calculateAverageTaste() {
510         averageSpicy = (spicyNum != 0) ? (int) Math.round(averageSpicy / spicyNum) : averageSpicy;
511         averageSweetness = (sweetnessNum != 0) ? (int) Math.round(averageSweetness / sweetnessNum) : averageSweetness;
512         averageAcidity = (acidityNum != 0) ? (int) Math.round(averageAcidity / acidityNum) : averageAcidity;
513     }
514 
515     public void giveTaste(String name, int num, int tasteLevel, Menu menu) {
516         int flag = new inputmat().findcage(menu.searthSpecialDish(name).taste);
517         switch (flag) {
518             case 1:
519                 updateTasteAverages(tasteLevel, 0, 0, num);
520                 break;
521             case 2:
522                 updateTasteAverages(0, tasteLevel, 0, num);
523                 break;
524             case 3:
525                 updateTasteAverages(0, 0, tasteLevel, num);
526                 break;
527         }
528         calculateAverageTaste();
529     }
530 }
531 
532 class lastPrint{
533     ArrayList<Table> tables = new ArrayList<>();
534     PersonPay[] personPays;
535     int p;
536     inputmat mat = new inputmat() ;
537     public void payPrint(){
538         for(int k=0;k<p;k++){
539             for(Table table:tables){
540                 if(table.tableName.equals(personPays[k].name)){
541                     personPays[k].payPrice+=table.tablePrice();
542                 }
543             }
544         }
545         for(int k=0;k<p-1;k++){
546             for(int l=k+1;l<p;l++){
547                 if(personPays[k].name.toLowerCase().compareTo(personPays[l].name.toLowerCase())>0) {
548                     PersonPay x;
549                     x=personPays[l];
550                     personPays[l]=personPays[k];
551                     personPays[k]=x;
552                 }
553             }
554         }
555         for(int k=0;k<p;k++){
556             System.out.println(personPays[k].name+" "+personPays[k].telephoneNum+" "+personPays[k].payPrice);
557         }
558     }
559 }
560 class PersonPay{
561     String name;
562     String telephoneNum;
563     int payPrice;
564 }
565 class caicage{
566 
567 }
568 class inputmat{
569     String name1 = "川菜";
570     String name2 = "晋菜";
571     String name3 = "浙菜";
572     int flag ;
573     int datetime(String time){
574         DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy/M/d");
575         LocalDate date1= LocalDate.parse(time , formatter1); // 将字符串解析为LocalDate对象
576         DayOfWeek dayOfWeek = date1.getDayOfWeek();
577          int week =0;
578         if(dayOfWeek ==DayOfWeek.WEDNESDAY ) {
579             week = 3;
580             return week;
581         }
582         else if(dayOfWeek ==DayOfWeek.MONDAY) {
583             week = 1;
584             return week;
585         }
586         else if(dayOfWeek ==DayOfWeek.TUESDAY){
587             week = 2;
588         return week;
589         }
590         else if(dayOfWeek ==DayOfWeek.THURSDAY){
591             week = 4;
592         return week;}
593         else if(dayOfWeek ==DayOfWeek.FRIDAY) {
594             week = 5;
595             return week;
596         }
597         else if(dayOfWeek ==DayOfWeek.SATURDAY) {
598             week = 6;
599             return week;
600         }
601         else if(dayOfWeek ==DayOfWeek.SUNDAY) {
602             week = 7;
603             return week;
604         }
605         return 0;
606     }
607     int findcage(String s) {
608         flag = 0;
609         if (s.matches(name1)) {
610             flag = 1;
611             return flag;
612         }
613         else if(s.matches(name2) ){
614             flag = 2;
615             return flag;
616         }
617         else if(s.matches(name3) ){
618             flag = 3;
619             return flag;
620         }
621         return flag;
622     }
623     public String spicyLevel(int averageSpicy){
624         switch (averageSpicy) {
625             case 0:
626                 return "不辣";
627             case 1:
628                 return "微辣";
629             case 2:
630                 return "稍辣";
631             case 3:
632                 return "辣";
633             case 4:
634                 return "很辣";
635             case 5:
636                 return "爆辣";
637             default:
638                 return null;
639         }
640     }
641 
642     public String acidityLevel(int averageAcidity){
643         switch (averageAcidity) {
644             case 0:
645                 return "不酸";
646             case 1:
647                 return "微酸";
648             case 2:
649                 return "稍酸";
650             case 3:
651                 return "酸";
652             case 4:
653                 return "很酸";
654             default:
655                 return null;
656         }
657     }
658 
659     public String sweetnessLevel(int averageSweetness) {
660         switch (averageSweetness) {
661             case 0:
662                 return "不甜";
663             case 1:
664                 return "微甜";
665             case 2:
666                 return "稍甜";
667             case 3:
668                 return "甜";
669             default:
670                 return null;
671         }
672     }
673  String p1 = "([1-9][0-9]*)";
674     String p2 = "(\\S+)";
675     String p3 = "(delete)";
676     String p4 = "([0-9]*)";
677     String p5 = "T";
678     String table = "^(table)( )([1-9][0-9]*)( )(:)( )(\\S+)( )((136|133|135|180|181|189)[0-9]{8})( )([0-9]{4})(/)([0-9]|[0-9]{2})(/)([0-9]|[0-9]{2})( )([0-9]|[0-9]{2})(/)([0-9]|[0-9]{2})(/)([0-9]|[0-9]{2})$";
679     String menu1 = p2+"( )([1-9][0-9]*)$";
680     String menu2 = "^(\\S+)( )(\\S+)( )([1-9][0-9]*)( )"+p5;
681     String oeder1 = "^([1-9][0-9]*)( )(\\S+)( )([1-9][0-9]*)( )([1-9][0-9]*)$";
682     String oder2 = "^([1-9][0-9]*)( )(\\S+)( )([0-9]+)( )([1-9][0-9]*)( )([1-9][0-9]*)$";
683     String oder3 = p1+" "+p3 ;//"([1-9][0-9]*)( )(delete)";
684     String oder4 = "^([1-9][0-9]*)( )([1-9][0-9]*)( )(\\S+)( )([1-9][0-9]*)( )([1-9][0-9]*)$";
685     String oder5 = "^([1-9][0-9]*)( )([1-9][0-9]*)( )(\\S+)( )"+p4+"( )([1-9][0-9]*)( )([1-9][0-9]*)$";
686     int inpumat(String s){
687         if(s.matches(table) )
688             return 1;
689         else if(s.matches(menu1) )
690             return 2;
691         else if(s.matches(menu2) )
692             return 3;
693         else if(s.matches(oeder1) )
694             return 4;
695         else if(s.matches(oder2) )
696             return 5;
697         else if(s.matches(oder3) )
698             return 6;
699         else if(s.matches(oder4) )
700             return 7;
701         else if(s.matches(oder5) )
702             return 8;
703         return 0;
704     }
705     void error(int a, int flag) {
706         switch (flag) {
707             case 1:
708                 if (a < 0 || a > 5) {
709                     System.out.println("spicy num out of range :" + a);
710                 }
711                 break;
712             case 2:
713                 if (a < 0 || a > 4)
714                     System.out.println("acidity num out of range :" + a);
715                 break;
716             case 3:
717                 if (a < 0 || a > 3)
718                     System.out.println("sweetness num out of range :" + a);
719                 break;
720         }
721     }
722 }

类图如下:

代码难度如下:

 

分析:

  1. 主类 (Main):

    • 程序从 Main 类的 main 方法开始执行。
    • 使用 BufferedReader 从控制台读取输入。
    • 声明了各种数组和对象,用于存储有关桌子、菜品、订单等的信息。
  2. 桌子类 (Table):

    • 代表餐厅中的一张桌子,具有属性如 tableNumtableNametelephoneNum 等。
    • 包含用于计算桌子总价、处理基于时间的折扣和更新口味平均值的方法。
  3. 菜品和特色菜品类:

    • DishSpecialDish 是分别代表常规和特色菜品的类。
    • 它们具有属性如 nametasteunit_price
  4. 菜单类 (Menu):

    • 管理餐厅的菜单,包括常规和特色菜品。
    • 提供搜索菜品和添加新菜品的方法。
  5. 订单类 (Order):

    • 代表一个订单,包含 Record 对象数组。
    • 计算和管理订单的总价。
  6. 记录类 (Record):

    • 代表订单中一道菜的记录。
    • 包含菜品、份数、数量以及是否为特色菜的信息。
  7. 最终打印类 (lastPrint):

    • 管理最终付款详情的打印输出。
    • 计算并打印每个人需要支付的总金额。
  8. 个人支付类 (PersonPay):

    • 代表个人的支付信息,包括姓名、电话号码和支付金额。
  9. caicage 类和 inputmat 类:

    • caicage 类为空,似乎未被使用。
    • inputmat 类包含处理各种输入模式的方法,包括创建桌子、更新菜单和录入订单。
  10. 日期时间格式化:

  • 使用 DateTimeFormatterLocalDate 解析和格式化日期和时间。
  1. 循环和用户输入:
  • 程序在循环中运行,不断读取用户输入,直到输入 "end" 命令为止。
  1. 错误处理:
  • 实现了一些基本的错误处理,例如在添加到订单之前检查菜品是否存在。
  1. 打印结果:
  • 最终结果包括每张桌子的总价,考虑到折扣和口味平均值。

期中考试

7-1 测验1-圆类设计

 

创建一个圆形类(Circle),私有属性为圆的半径,从控制台输入圆的半径,输出圆的面积

输入格式:

输入圆的半径,取值范围为(0,+∞),输入数据非法,则程序输出Wrong Format,注意:只考虑从控制台输入数值的情况

输出格式:

输出圆的面积(保留两位小数,可以使用String.format(“%.2f”,输出数值)控制精度)

输入样例:

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

2.35

输出样例:

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

17.35
我的代码如下:
 1 import java.util.Scanner;
 2 public class Main{
 3     public static void main(String[] args) {
 4         Scanner scanner = new Scanner(System.in);
 5         double radius = scanner.nextDouble();
 6         Circle circle = new Circle();
 7         circle.setRadius(radius);
 8         double area = circle.getArea();
 9         if (radius > 0) {
10             String formattedArea = String.format("%.2f", area);
11             System.out.println(formattedArea);
12         }else {
13             System.out.println("Wrong Format");
14         }
15     }
16 }
17 class Circle{
18     private double radius;
19     public void setRadius(double radius) {
20             this.radius = radius;
21     }
22 
23     public double getArea() {
24         return Math.PI * radius * radius;
25     }
26 }

此题较为简单,不进行追加分析

7-2 测验2-类结构设计

设计一个矩形类,其属性由矩形左上角坐标点(x1,y1)及右下角坐标点(x2,y2)组成,其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数),求得该矩形的面积。类设计如下图:


image.png

输入格式:

分别输入两个坐标点的坐标值x1,y1,x2,y2。

输出格式:

输出该矩形的面积值(保留两位小数)。

输入样例:

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

6 5.8 -7 8.9

输出样例:

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

40.30

我的代码如下:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5     
 6     Scanner input = new Scanner(System.in);
 7 
 8     double x1 = input.nextDouble();
 9     double y1 = input.nextDouble();
10     double x2 = input.nextDouble();
11     double y2 = input.nextDouble();
12 
13     Point leftTopPoint = new Point(x1, y1);
14     Point lowerRightPoint = new Point(x2, y2);
15 
16     Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
17     System.out.printf("%.2f", rectangle.area());
18 
19 
20     }
21 
22 }
23 abstract class Shape {
24     public abstract double area();
25 }
26 class Rectangle extends Shape {
27     private Point leftTopPoint;
28     private Point lowerRightPoint;
29 
30     public Rectangle(Point leftTopPoint, Point lowerRightPoint) {
31         this.leftTopPoint = leftTopPoint;
32         this.lowerRightPoint = lowerRightPoint;
33     }
34 
35     public Point getLeftTopPoint() {
36         return leftTopPoint;
37     }
38 
39     public void setLeftTopPoint(Point leftTopPoint) {
40         this.leftTopPoint = leftTopPoint;
41     }
42 
43     public Point getLowerRightPoint() {
44         return lowerRightPoint;
45     }
46 
47     public void setLowerRightPoint(Point lowerRightPoint) {
48         this.lowerRightPoint = lowerRightPoint;
49     }
50 
51     @Override
52     public double area() {
53         double length = Math.abs(lowerRightPoint.getX() - leftTopPoint.getX());
54         double width = Math.abs(lowerRightPoint.getY() - leftTopPoint.getY());
55         return length * width;
56     }
57 }
58 class Point {
59     private double x;
60     private double y;
61     
62     public Point(double x, double y) {
63         this.x = x;
64         this.y = y;
65     }
66     
67     public double getX() {
68         return x;
69     }
70     
71     public double getY() {
72         return y;
73     }
74 }

此题并不困难,不进行分析

7-3 测验3-继承与多态

将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类,类图如下所示:


image.png

试编程完成如上类图设计,主方法源码如下(可直接拷贝使用):

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        int choice = input.nextInt();
        
        switch(choice) {
        case 1://Circle
            double radiums = input.nextDouble();
            Shape circle = new Circle(radiums);
            printArea(circle);
            break;
        case 2://Rectangle
            double x1 = input.nextDouble();
            double y1 = input.nextDouble();
            double x2 = input.nextDouble();
            double y2 = input.nextDouble();
            
            Point leftTopPoint = new Point(x1,y1);
            Point lowerRightPoint = new Point(x2,y2);
            
            Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
            
            printArea(rectangle);
            break;
        }
        
    }

其中,printArea(Shape shape)方法为定义在Main类中的静态方法,体现程序设计的多态性。

输入格式:

输入类型选择(1或2,不考虑无效输入)
对应图形的参数(圆或矩形)

输出格式:

图形的面积(保留两位小数)

输入样例1:

1
5.6

输出样例1:

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

98.52

输入样例2:

2
5.6
-32.5
9.4
-5.6
 

输出样例2:

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

102.22

我的代码如下:

  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 
  7         int choice = input.nextInt();
  8 
  9         switch (choice) {
 10             case 1:// Circle
 11                 double radius = input.nextDouble();
 12                 if (radius <= 0) {
 13             System.out.println("Wrong Format");
 14     }else{
 15                 Shape circle = new Circle(radius);
 16                 printArea(circle);}
 17                 break;
 18             case 2:// Rectangle
 19                 double x1 = input.nextDouble();
 20                 double y1 = input.nextDouble();
 21                 double x2 = input.nextDouble();
 22                 double y2 = input.nextDouble();
 23 
 24                 Point leftTopPoint = new Point(x1, y1);
 25                 Point lowerRightPoint = new Point(x2, y2);
 26 
 27                 Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
 28 
 29                 printArea(rectangle);
 30                 break;
 31         }
 32 
 33         input.close();
 34     }
 35 
 36     public static void printArea(Shape shape) {
 37         System.out.printf("%.2f", shape.area());
 38     }
 39 }
 40 abstract class Shape {
 41     public abstract double area();
 42 }
 43 class Circle extends Shape {
 44     private double radius;
 45 
 46     public Circle(double radius) {
 47         
 48             this.radius = radius;
 49     
 50     }
 51 
 52     public double getRadius() {
 53         return radius;
 54     }
 55 
 56     public void setRadius(double radius) {
 57         
 58             this.radius = radius;
 59         
 60     }
 61 
 62     @Override
 63     public double area() {
 64         return Math.PI * radius * radius;
 65     }
 66 }
 67 class Rectangle extends Shape {
 68     private Point leftTopPoint;
 69     private Point lowerRightPoint;
 70 
 71     public Rectangle(Point leftTopPoint, Point lowerRightPoint) {
 72         this.leftTopPoint = leftTopPoint;
 73         this.lowerRightPoint = lowerRightPoint;
 74     }
 75 
 76     public Point getLeftTopPoint() {
 77         return leftTopPoint;
 78     }
 79 
 80     public void setLeftTopPoint(Point leftTopPoint) {
 81         this.leftTopPoint = leftTopPoint;
 82     }
 83 
 84     public Point getLowerRightPoint() {
 85         return lowerRightPoint;
 86     }
 87 
 88     public void setLowerRightPoint(Point lowerRightPoint) {
 89         this.lowerRightPoint = lowerRightPoint;
 90     }
 91 
 92     @Override
 93     public double area() {
 94         double length = Math.abs(lowerRightPoint.getX() - leftTopPoint.getX());
 95         double width = Math.abs(lowerRightPoint.getY() - leftTopPoint.getY());
 96         return length * width;
 97     }
 98 }
 99 class Point {
100     private double x;
101     private double y;
102     
103     public Point(double x, double y) {
104         this.x = x;
105         this.y = y;
106     }
107     
108     public double getX() {
109         return x;
110     }
111     
112     public double getY() {
113         return y;
114     }
115 }

类图如下:

 代码难度如下:

 分析:

  1. Main 类:

    • main 方法中使用 Scanner 从控制台获取用户的选择。
    • 根据用户的选择(1 或 2),创建相应的图形对象(CircleRectangle)。
    • 调用 printArea 方法打印图形的面积。
  2. printArea 方法:

    • 接收一个 Shape 类型的参数,调用其 area 方法,并使用 printf 打印面积值。
  3. Shape 抽象类:

    • 声明了一个抽象方法 area,要求子类实现该方法。
    • 用于表示各种形状的基类。
  4. Circle 类:

    • 继承自 Shape 类。
    • 包含一个私有的半径属性。
    • 提供构造方法、获取半径的方法、设置半径的方法以及实现 area 方法计算圆的面积。
  5. Rectangle 类:

    • 继承自 Shape 类。
    • 包含两个私有的 Point 对象,分别表示矩形的左上角和右下角坐标。
    • 提供构造方法、获取左上角和右下角坐标的方法、设置坐标的方法以及实现 area 方法计算矩形的面积。
  6. Point 类:

    • 表示一个点,包含 x 和 y 坐标。
    • 提供构造方法和获取坐标的方法。
  7. 用户输入和条件检查:

    • 使用 Scanner 获取用户输入。
    • 对用户输入的半径、矩形的两个点坐标进行检查,如果不符合条件(例如半径小于等于0),输出错误提示。
  8. 输出结果:

    • 使用 printf 打印计算得到的面积,保留两位小数。

我通过类的继承和抽象类的使用实现了简单的图形面积计算功能。运行代码后可以选择计算圆的面积或矩形的面积,然后输入相应的参数,程序将计算并输出结果。

7-4 测验4-抽象类与接口

在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。
提示:题目中Shape类要实现Comparable接口。

其中,Main类源码如下(可直接拷贝使用):

public class Main {
    public static void main(String\[\] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        ArrayList<Shape> list = new ArrayList<>();    

        int choice = input.nextInt();

        while(choice != 0) {
            switch(choice) {
            case 1://Circle
                double radiums = input.nextDouble();
                Shape circle = new Circle(radiums);
                list.add(circle);
                break;
            case 2://Rectangle
                double x1 = input.nextDouble();
                double y1 = input.nextDouble();
                double x2 = input.nextDouble();
                double y2 = input.nextDouble();            
                Point leftTopPoint = new Point(x1,y1);
                Point lowerRightPoint = new Point(x2,y2);
                Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
                list.add(rectangle);
                break;
            }
            choice = input.nextInt();
        }    

        list.sort(Comparator.naturalOrder());//正向排序

        for(int i = 0; i < list.size(); i++) {
            System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
        }    
    }    
}

输入格式:

输入图形类型(1:圆形;2:矩形;0:结束输入)

输入图形所需参数

输出格式:

按升序排序输出列表中各图形的面积(保留两位小数),各图形面积之间用空格分隔。

输入样例:

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

1
2.3
2
3.2
3
6
5
1
2.3
0

输出样例:

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

5.60 16.62 16.62 

我的代码如下:

  1 import java.util.ArrayList;
  2 import java.util.Comparator;
  3 import java.util.Scanner;
  4 
  5 public class Main {
  6     public static void main(String[] args) {
  7         Scanner input = new Scanner(System.in);
  8         ArrayList<Shape> list = new ArrayList<>();
  9 
 10         int choice = input.nextInt();
 11 
 12         while (choice != 0) {
 13             switch (choice) {
 14                 case 1: // Circle
 15                     double radius = input.nextDouble();
 16                     Shape circle = new Circle(radius);
 17                     list.add(circle);
 18                     break;
 19                 case 2: // Rectangle
 20                     double x1 = input.nextDouble();
 21                     double y1 = input.nextDouble();
 22                     double x2 = input.nextDouble();
 23                     double y2 = input.nextDouble();
 24                     Point leftTopPoint = new Point(x1, y1);
 25                     Point lowerRightPoint = new Point(x2, y2);
 26                     Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
 27                     list.add(rectangle);
 28                     break;
 29             }
 30             choice = input.nextInt();
 31         }
 32 
 33         list.sort(Comparator.naturalOrder());
 34 
 35         for (Shape shape : list) {
 36             System.out.print(String.format("%.2f", shape.getArea()) + " ");
 37         }
 38     }
 39 }
 40 
 41 abstract class Shape implements Comparable<Shape> {
 42     public abstract double area();
 43 
 44     public double getArea() {
 45         return area();
 46     }
 47 
 48     @Override
 49     public int compareTo(Shape other) {
 50         return Double.compare(this.area(), other.area());
 51     }
 52 }
 53 
 54 class Circle extends Shape {
 55     private double radius;
 56 
 57     public Circle(double radius) {
 58         this.radius = radius;
 59     }
 60 
 61     @Override
 62     public double area() {
 63         return Math.PI * radius * radius;
 64     }
 65 }
 66 
 67 class Rectangle extends Shape {
 68     private Point leftTopPoint;
 69     private Point lowerRightPoint;
 70 
 71     public Rectangle(Point leftTopPoint, Point lowerRightPoint) {
 72         this.leftTopPoint = leftTopPoint;
 73         this.lowerRightPoint = lowerRightPoint;
 74     }
 75 
 76     @Override
 77     public double area() {
 78         double length = Math.abs(lowerRightPoint.getX() - leftTopPoint.getX());
 79         double width = Math.abs(lowerRightPoint.getY() - leftTopPoint.getY());
 80         return length * width;
 81     }
 82 }
 83 
 84 class Point {
 85     private double x;
 86     private double y;
 87 
 88     public Point(double x, double y) {
 89         this.x = x;
 90         this.y = y;
 91     }
 92 
 93     public double getX() {
 94         return x;
 95     }
 96 
 97     public double getY() {
 98         return y;
 99     }
100 }

类图如下:

 代码难度如下:

 分析:

  1. Main 类:

    • 创建了一个 ArrayList 类型的列表 list 用于存储图形对象。
    • 使用 while 循环,允许用户输入多个图形,直到用户输入 0 为止。
    • 根据用户的选择(1 或 2),创建相应的图形对象(CircleRectangle),并将其添加到列表中。
    • 用户输入结束后,对列表中的图形对象进行排序(按面积升序)。
    • 遍历列表并输出各个图形的面积。
  2. Shape 抽象类:

    • 实现了 Comparable 接口,使得图形对象可以进行比较。
    • 增加了 getArea 方法,用于获取图形的面积。
    • 实现了 compareTo 方法,用于排序时比较图形的面积。
  3. Circle 类 和 Rectangle 类:

    • 没有大的变化,仍然继承自 Shape 类,实现了各自的 area 方法。
  4. Point 类:

    • 没有变化,用于表示一个点。
  5. 用户输入:

    • 用户可以输入多个图形,每次输入一个图形的相关信息,直到输入 0 结束。
    • 对输入的坐标和半径进行检查,例如,确保半径大于 0,以避免不合理的图形。
  6. 列表排序:

    • 使用 list.sort(Comparator.naturalOrder()) 对图形列表进行排序。这里利用了 Comparable 接口中的比较方法。
  7. 输出结果:

    • 遍历排序后的列表,使用 String.format 打印各个图形的面积,保留两位小数。

7-4在7-3的基础上增加了列表和排序功能,能够输入多个图形,然后按照面积升序输出这些图形的面积。

三.踩坑心得

1、注意检查价格算法,特别是特色菜的定价算法和打折时间。确保算法正确并准确反映实际情况

2、ArrayList 使用:
  • 潜在问题: 操作 ArrayList 时可能会出现索引越界、空指针等问题。
  • 踩坑心得: 注意数组和列表的索引从 0 开始。在使用列表之前,确保它不为 null,并在添加、删除元素时小心边界条件

3、异常处理:

  • 潜在问题: Java 中的输入操作(例如 nextIntnextDouble)可能引发异常,尤其是在用户输入无效数据时。
  • 踩坑心得: 使用 try-catch 块捕获异常,确保程序在出现异常时能够 gracefully 处理。

四.主要困难及改进建议

  1. 输入验证:

    • 在接收用户输入时,添加验证以确保输入的半径和坐标等参数是合法的。可以在输入前使用循环来不断提示用户输入,直到得到有效的输入。
  2. 面向对象设计:

    • 尽量遵循单一职责原则,确保每个类都有清晰的职责。我的代码在 Shape 类中,getArea 方法似乎有些多余,因为 area 方法本身已经提供了相同的功能。
  3. 代码重复:

    • 期中考试部分可以将用户输入半径和坐标的部分提取成方法,以减少重复代码。

五、总结

  通过编写这个菜单系统,我深入学习了如何使用Java编程语言构建基本的命令行应用程序。在这个过程中,我掌握了面向对象编程的基本概念和原则,并成功地将它们应用到项目中。

  在学习中,我了解了类的定义和使用,学会了如何创建和操作对象,并学习了如何设计和组织代码结构。异常处理成为我编程技能中的一部分,我学到了如何在程序中有效地处理错误和异常情况,提高了代码的健壮性。

  通过这个项目,我还学会了使用集合类,如ArrayList和HashMap,来存储和管理数据,将它们应用于系统的各项功能。通过自主思考和查阅相关资料,我成功地解决了一些编程中遇到的问题。

  这个过程也提高了我对Java编程的理解能力。逐步完善自己的设计是一项具有挑战性但令人愉悦的任务。我学到了编程思维,并对开闭原则、继承和多态有了更深入的了解。

  在编写PTA时,我认识到自己的代码可读性较差,条理性不够清晰。这让我意识到注重代码书写习惯的重要性。因此,学习Java不仅对今后学习其他编程语言有帮助,还培养了我作为一个编程人员应具备的良好心理素质。

标签:空格,记录,int,BLOG,英文,菜品,new
From: https://www.cnblogs.com/zzz3898/p/17837182.html

相关文章

  • weblogic导出excel遇到的问题记录
    weblogic使用poi导入jar包冲突解决:https://www.cnblogs.com/ljch/p/12045160.htmlhttps://blog.csdn.net/teigakushi/article/details/17305533https://blog.csdn.net/liushengbaba/article/details/84632236仅针对10.3及以上版本。在WEB-INF下面添加weblogic.xml文件:https......
  • 锦城 Week0 Blog 对拍 Debug 复杂度
    Blog我们在学习的时候,需要些一些笔记,把所学记录和整理下来,作为计算机专业的学生,不太可能用纸笔来记笔记,所以我们需要写博客(Blog)众多大佬都有自己的博客美团技术团队Martian148的博客写博客可以帮助我们更好的吸收,消化知识,把自己所学的东西用简单的话语讲出来(费曼学习法)......
  • 博客园cnblogs的代码折叠
    实现折叠的代码如下:<details><summary>查看代码</summary><pre><code>这里写需要被折叠的代码</code></pre></details>效果如下:查看代码这里写需要被折叠的代码参考链接:https://www.cnblogs.c......
  • dsBlog前后台博客系统
    博客简介:本博客采用SpringBoot+LayUI做为基础,进行的博客系统开发,与boot+vue相比,更为适合开发简单的系统,并且更容易上手,简单!高效!更易上手!SpringBoot+LayUI:快速开发:LayUI是一个简单的UI框架,它提供了易于使用的组件,可以快速构建界面。搭配SpringBoot,你可以迅速开发出后台......
  • scrapy解析数据,配置文件,整站爬取cnblogs,持久化
    1scrapy解析数据......
  • cnblogs 侧边栏
    <scripttype="text/javascript">window.cnblogsConfig={info:{name:'Martian148',//用户名||不配置默认取博客园名称startDate:'2018-10-13',//入园时间,年-月-日。入园时间查看方法:鼠标停留园龄时间上,会显示入园时间......
  • JVM系列-第7章-对象的实例化内存布局与访问定位-cnblog
    title:JVM系列-第7章-对象的实例化内存布局与访问定位tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第7章-对象的实例化内存布局与访问定位。cover:'https://gitee.com/youthlql/randombg/raw/master/lo......
  • JVM系列-第9章-StringTable(字符串常量池)-cnblog
    title:JVM系列-第9章-StringTable(字符串常量池)tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第9章-StringTable(字符串常量池)。cover:'https://gitee.com/youthlql/randombg/raw/master/logo/jvm.png......
  • JVM系列-第8章-执行引擎-cnblog
    title:JVM系列-第8章-执行引擎tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第8章-执行引擎。cover:'https://gitee.com/youthlql/randombg/raw/master/logo/jvm.png'abbrlink:408712f4date:2020-11......
  • JVM系列-第10章-垃圾回收概述和相关算法-cnblog
    title:JVM系列-第10章-垃圾回收概述和相关算法tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第10章-垃圾回收概述和相关算法。cover:'https://gitee.com/youthlql/randombg/raw/master/logo/jvm.png'ab......