第二次博客作业
前言
这是第二次博客作业,总结了近三次PTA大作业的完成情况,这三次的大作业难度逐渐增大,完全理不清逻辑,真的越想越混乱,代码写的也是很乱,没有一个整体的框架结构,读起来很困难,没有学到java程序编写的真谛,总之对于我,一个逻辑很差很差的人来说,越来越复杂的题目,写起来真的痛苦,到后面的题目,基本上就是毫无章法的加功能,为了题目而写题目,学起来好累TAT。
关于类和整个程序的设计:
学了很多新的结构设计的方法,和一些辅助清晰思路的方法,例如:画类图、画时序图,但是我还是不能很熟练的抽象出方法和各个类之间的联系,导致在编写复杂代码的时候会思维混乱不能有一个很好的代码结构。课堂上还学习了一些面向对象设计的原则,比如:里氏代换原则等,学习这些原则一定程度上帮助我在设计和编写代码的时候可以更加的规范和条理清晰。
三次题目集的知识点、题量、难度等情况:
(对于重难点题目将会给出完整题目)
第四次大作业:
7-4 菜单计价程序-2:这是点菜系列的第二次迭代,相比于前一次增加了可输入菜单等功能
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。
菜单由一条或多条菜品记录组成,每条记录一行
每条菜品记录包含:菜名、基础价格 两个信息。
订单分:点菜记录和删除信息。每一类信息都可包含一条或多条记录,每条记录一行。
点菜记录包含:序号、菜名、份额、份数。
份额可选项包括:1、2、3,分别代表小、中、大份。
删除记录格式:序号 delete
标识删除对应序号的那条点菜记录。
不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格2。
如果计算出现小数,按四舍五入的规则进行处理。
参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
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)//根据序号查找一条记录
}
输入格式:
菜品记录格式:
菜名+英文空格+基础价格
如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。
点菜记录格式:
序号+英文空格+菜名+英文空格+份额+英文空格+份数
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
删除记录格式:序号 +英文空格+delete
最后一条记录以“end”结束。
输出格式:
按顺序输出每条订单记录的处理信息,
每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。
如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名
如果删除记录的序号不存在,则输出“delete error”
最后输出订单上所有菜品的总价(整数数值),
本次题目不考虑其他错误情况,如:菜单订单顺序颠倒、不符合格式的输入、序号重复等。
7-1 菜单计价程序-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+英文空格+桌号+“:”+英文空格+当前桌的总价
本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。
输入格式:桌号标识格式: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+英文空格+桌号+“:”+英文空格+当前桌的总价
本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。
第五次大作业:
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+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价
第六次大作业:
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+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格
最后按拼音顺序输出每位客户(不考虑客户同名或拼音相同的情况)的支付金额,格式: 用户姓名+英文空格+手机号+英文空格+支付总金额,按输入顺序排列。
期中考试
期中考试考了类的基本设计、继承、多态、接口等,关于圆和四边形的类设计,我写题目的时候保存了一个编程题的题目,也是最后一个编程题,关于接口的,我编写的还是很不规范。
在测验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
设计与分析与主要问题和其解决方法
(这里只会提供重点题目的代码)
第四次大作业:
菜单2
1 import java.math.BigDecimal; 2 import java.util.HashMap; 3 import java.util.Map; 4 5 class Dish { 6 String name; 7 int unit_price; 8 9 public Dish(String name, int unit_price) { 10 this.name = name; 11 this.unit_price = unit_price; 12 } 13 14 public long getPrice(int portion) { 15 double price = unit_price; 16 if (portion == 2) { 17 price *= 1.5; 18 } else if (portion == 3) { 19 price *= 2; 20 } 21 return Math.round(price); 22 } 23 } 24 25 class Menu { 26 static Dish[] dishes; 27 28 public Dish addDish(String dishName, int unit_price) { 29 Dish dish = new Dish(dishName, unit_price); 30 for (int i = 0; i < dishes.length; i++) { 31 if (dishes[i] != null && dishes[i].name.equals(dishName)) { 32 dishes[i] = dish; 33 return dish; 34 } 35 } 36 // 如果未找到相同菜名的菜品记录,则添加到新的位置 37 for (int i = 0; i < dishes.length; i++) { 38 if (dishes[i] == null) { 39 dishes[i] = dish; 40 break; 41 } 42 } 43 return dish; 44 } 45 46 public static Dish searchDish(String dishName) { 47 for (Dish dish : dishes) { 48 if (dish != null && dish.name.equals(dishName)) { 49 return dish; 50 } 51 } 52 return null; 53 } 54 } 55 56 class Record { 57 int orderNum; 58 Dish dish; 59 int portion; 60 61 public long getPrice() { 62 if(dish != null) 63 return dish.getPrice(portion); 64 else return 0; 65 } 66 } 67 68 class Order { 69 Record[] records; 70 71 public Record addARecord(int orderNum, String dishName, int portion, int num) { 72 Record record = new Record(); 73 record.orderNum = orderNum; 74 record.dish = Menu.searchDish(dishName); 75 record.portion = portion; 76 77 int index = 0; 78 while (index < records.length && records[index] != null) { 79 index++; 80 } 81 82 if (index < records.length) { 83 records[index] = record; 84 } else { 85 System.out.println("记录已满,无法添加新的点菜记录。"); 86 } 87 return record; 88 } 89 90 public void delARecordByOrderNum(int orderNum) { 91 for (int i = 0; i < records.length; i++) { 92 if (records[i] != null && records[i].orderNum == orderNum) { 93 records[i] = null; 94 break; 95 } 96 } 97 } 98 99 public Record findRecordByNum(int orderNum) { 100 for (Record record : records) { 101 if (record != null && record.orderNum == orderNum) { 102 return record; 103 } 104 } 105 return null; 106 } 107 108 public long getTotalPrice() { 109 long totalPrice = 0; 110 for (Record record : records) { 111 if (record != null) { 112 totalPrice =totalPrice + record.getPrice(); 113 } 114 } 115 return totalPrice; 116 } 117 } 118 119 120 public class PTA4_4_order2 { 121 private static Map<Integer,BigDecimal> number= new HashMap<Integer,BigDecimal>(); 122 public static void main(String[] args) { 123 BigDecimal bigDecimal = new BigDecimal(0L); 124 Menu menu = new Menu(); 125 menu.dishes = new Dish[100]; 126 127 Order order = new Order(); 128 order.records = new Record[100]; 129 130 java.util.Scanner scanner = new java.util.Scanner(System.in); 131 String input = scanner.nextLine(); 132 while (true) { 133 String[] splitInput = input.split(" "); 134 // 处理菜单记录 135 if (splitInput.length == 2) { 136 String dishName = splitInput[0]; 137 String PO = splitInput[1]; 138 if (!PO.equals("delete")){ 139 int unitPrice = Integer.parseInt(splitInput[1]); 140 menu.addDish(dishName, unitPrice); 141 }else { 142 int orderNum = Integer.parseInt(splitInput[0]); 143 Record record = order.findRecordByNum(orderNum); 144 BigDecimal o = number.get(orderNum); 145 if (o != null){ 146 bigDecimal = bigDecimal.subtract(o); 147 } 148 if (record == null) { 149 System.out.println("delete error;"); 150 } else { 151 order.delARecordByOrderNum(orderNum); 152 } 153 } 154 } 155 // 处理订单记录 156 else if (splitInput.length == 4) { 157 int orderNum = Integer.parseInt(splitInput[0]); 158 String dishName = splitInput[1]; 159 int portion = Integer.parseInt(splitInput[2]); 160 int num = Integer.parseInt(splitInput[3]); 161 Record record = order.addARecord(orderNum, dishName, portion, num); 162 if (record.dish == null) { 163 System.out.println(dishName + " does not exist"); 164 } else { 165 long totalPrice = record.getPrice() * num; 166 BigDecimal bigDecimal1 = BigDecimal.valueOf(totalPrice); 167 number.put(orderNum,bigDecimal1); 168 bigDecimal = bigDecimal.add(bigDecimal1); 169 System.out.println(orderNum + " " + dishName + " " + totalPrice); 170 } 171 } 172 // 处理删除记录 173 else if (splitInput[1].equals("delete")) { 174 int orderNum = Integer.parseInt(splitInput[0]); 175 176 Record record = order.findRecordByNum(orderNum); 177 if (record == null) { 178 System.out.println("delete error"); 179 } else { 180 order.delARecordByOrderNum(orderNum); 181 } 182 } 183 input = scanner.nextLine(); 184 if (input.equals("end")){ 185 break; 186 } 187 } 188 scanner.close(); 189 System.out.print(bigDecimal.setScale(1, BigDecimal.ROUND_HALF_UP).intValue()); 190 } 191 }
类图如下:
题目的分析如下:
这个题目需要设计一个点菜计价程序,可以根据输入的菜单和订单信息,计算并输出总价格。首先,你需要设计三个类:菜品类(Dish)、菜谱类(Menu)、点菜记录类(Record)和订单类(Order)。
菜品类(Dish)包含菜品名称和基础价格,以及计算菜品价格的方法。菜谱类(Menu)包含了一个菜品数组,可以根据菜名在菜谱中查找菜品信息,或者添加一道菜品信息。点菜记录类(Record)保存订单上的一道菜品记录,包含序号、菜品、份额和计价方法。订单类(Order)保存用户点的所有菜的信息,包括订单上的每一道记录,计算订单的总价,添加一条菜品信息到订单中以及根据序号删除一条记录。
输入格式包括菜单和订单,以"end"结束。菜单的记录格式为菜名+英文空格+基础价格,而点菜记录格式为序号+英文空格+菜名+英文空格+份额+英文空格+份数。删除记录格式为序号+英文空格+delete。输出格式包括每条订单记录的处理信息,然后输出订单上所有菜品的总价(整数数值)。
需要注意的是,如果订单中包含不能识别的菜名,则输出“** does not exist”,如果删除记录的序号不存在,则输出“delete error”。
在程序中,需要对输入进行解析,创建菜单和订单对象,并根据订单进行计价。最后,输出每条订单记录的处理信息和订单的总价。
菜单3
1 import java.math.BigDecimal; 2 import java.time.LocalDate; 3 import java.time.format.DateTimeFormatter; 4 import java.time.format.DateTimeParseException; 5 import java.util.Date; 6 import java.util.HashMap; 7 import java.util.Map; 8 import java.util.Timer; 9 import java.time.DayOfWeek; 10 import java.time.LocalTime; 11 12 class Dish { 13 String name; 14 int unit_price; 15 16 public Dish(String name, int unit_price) { 17 this.name = name; 18 this.unit_price = unit_price; 19 } 20 21 public long getPrice(int portion) { 22 double price = unit_price; 23 if (portion == 2) { 24 price *= 1.5; 25 } else if (portion == 3) { 26 price *= 2; 27 } 28 return Math.round(price); 29 } 30 } 31 32 class Menu { 33 static Dish[] dishes; 34 35 public Dish addDish(String dishName, int unit_price) { 36 Dish dish = new Dish(dishName, unit_price); 37 for (int i = 0; i < dishes.length; i++) { 38 if (dishes[i] != null && dishes[i].name.equals(dishName)) { 39 dishes[i] = dish; 40 return dish; 41 } 42 } 43 // 如果未找到相同菜名的菜品记录,则添加到新的位置 44 for (int i = 0; i < dishes.length; i++) { 45 if (dishes[i] == null) { 46 dishes[i] = dish; 47 break; 48 } 49 } 50 return dish; 51 } 52 53 public static Dish searchDish(String dishName) { 54 for (Dish dish : dishes) { 55 if (dish != null && dish.name.equals(dishName)) { 56 return dish; 57 } 58 } 59 return null; 60 } 61 } 62 63 class Record { 64 int orderNum; 65 Dish dish; 66 int portion; 67 68 public long getPrice() { 69 if(dish != null) 70 return dish.getPrice(portion); 71 else return 0; 72 } 73 } 74 75 class Order { 76 Record[] records; 77 78 public Record addARecord(int orderNum, String dishName, int portion, int num) { 79 Record record = new Record(); 80 record.orderNum = orderNum; 81 record.dish = Menu.searchDish(dishName); 82 record.portion = portion; 83 84 int index = 0; 85 while (index < records.length && records[index] != null) { 86 index++; 87 } 88 89 if (index < records.length) { 90 records[index] = record; 91 } else { 92 System.out.println("记录已满,无法添加新的点菜记录。"); 93 } 94 return record; 95 } 96 97 public void delARecordByOrderNum(int orderNum) { 98 for (int i = 0; i < records.length; i++) { 99 if (records[i] != null && records[i].orderNum == orderNum) { 100 records[i] = null; 101 break; 102 } 103 } 104 } 105 106 public Record findRecordByNum(int orderNum) { 107 for (Record record : records) { 108 if (record != null && record.orderNum == orderNum) { 109 return record; 110 } 111 } 112 return null; 113 } 114 115 public long getTotalPrice() { 116 long totalPrice = 0; 117 for (Record record : records) { 118 if (record != null) { 119 totalPrice =totalPrice + record.getPrice(); 120 } 121 } 122 return totalPrice; 123 } 124 } 125 126 class Table{ 127 static int tableNum; 128 static Order order; 129 Date day; 130 Timer time; 131 // 验证日期是否合法 132 public static boolean isDateValid(String date1) { 133 try { 134 // 解析日期字符串 135 LocalDate.parse(date1); 136 return true; // 如果解析成功,则日期合法 137 } catch (DateTimeParseException e) { 138 return false; // 如果解析失败,则日期非法 139 } 140 } 141 142 public static boolean isWeekend(String dateString, String format) { 143 try { 144 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); 145 LocalDate date = LocalDate.parse(dateString, formatter); 146 DayOfWeek dayOfWeek = date.getDayOfWeek(); 147 return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY; 148 } catch (Exception e) { 149 return false; // 日期格式不正确 150 } 151 } 152 153 //判断是否在周末营业时间 154 public static boolean isWithinTimeRange(String timeString, String format) { 155 try { 156 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); 157 LocalTime time = LocalTime.parse(timeString, formatter); 158 LocalTime lowerBound = LocalTime.parse("09/30/00", formatter); 159 LocalTime upperBound = LocalTime.parse("21/30/00", formatter); 160 return lowerBound.compareTo(time) <= 0 && time.compareTo(upperBound) <= 0; 161 } catch (Exception e) { 162 return false; // 时间格式不正确 163 } 164 } 165 166 //判断是否在工作日中午营业时间 167 public static boolean isWithinTimeRange1(String timeString, String format) { 168 try { 169 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); 170 LocalTime time = LocalTime.parse(timeString, formatter); 171 LocalTime lowerBound = LocalTime.parse("10/30/00", formatter); 172 LocalTime upperBound = LocalTime.parse("14/30/00", formatter); 173 return lowerBound.compareTo(time) <= 0 && time.compareTo(upperBound) <= 0; 174 } catch (Exception e) { 175 return false; // 时间格式不正确 176 } 177 } 178 179 //判断是否在工作日晚上营业时间 180 public static boolean isWithinTimeRange2(String timeString, String format) { 181 try { 182 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); 183 LocalTime time = LocalTime.parse(timeString, formatter); 184 LocalTime lowerBound = LocalTime.parse("17/00/00", formatter); 185 LocalTime upperBound = LocalTime.parse("20/30/00", formatter); 186 return lowerBound.compareTo(time) <= 0 && time.compareTo(upperBound) <= 0; 187 } catch (Exception e) { 188 return false; // 时间格式不正确 189 } 190 } 191 192 static void tabletime(String[] splitInput){ 193 tableNum = Integer.parseInt(splitInput[1]); 194 String daytime = splitInput[2]; 195 String time = splitInput[3]; 196 //判断是否为周末 197 if (isWeekend(daytime, "yyyy/MM/dd")) { 198 System.out.println("table" + tableNum + ": "); 199 //判断是否在周末营业时间 200 if (isWithinTimeRange(time, "HH/mm/ss")) { 201 System.out.println("table" + tableNum + ": out of opening hours"); 202 } 203 } else { 204 System.out.println("table: " + tableNum); 205 if(isWithinTimeRange1(time,"HH/mm/ss")&&isWithinTimeRange2(time,"HH/mm/ss")){ 206 System.out.println("table" + tableNum + ": out of opening hours"); 207 } 208 if(!isWithinTimeRange1(time,"HH/mm/ss")){ 209 System.out.println(); 210 } 211 } 212 } 213 214 protected static int getDiscount(int discount){ 215 216 return 0; 217 } 218 219 } 220 221 public class PTA4_4_order3 { 222 private static Map<Integer,BigDecimal> number= new HashMap<Integer,BigDecimal>(); 223 public static void main(String[] args) { 224 BigDecimal bigDecimal = new BigDecimal(0L); 225 Menu menu = new Menu(); 226 menu.dishes = new Dish[100]; 227 228 Order order = new Order(); 229 order.records = new Record[100]; 230 Table table = new Table(); 231 232 java.util.Scanner scanner = new java.util.Scanner(System.in); 233 String input = scanner.nextLine(); 234 while (true) { 235 String[] splitInput = input.split(" "); 236 // 处理菜单记录 237 if (splitInput.length == 2) { 238 String dishName = splitInput[0]; 239 String PO = splitInput[1]; 240 if (!PO.equals("delete")){ 241 int unitPrice = Integer.parseInt(splitInput[1]); 242 menu.addDish(dishName, unitPrice); 243 }else { 244 int orderNum = Integer.parseInt(splitInput[0]); 245 Record record = order.findRecordByNum(orderNum); 246 BigDecimal o = number.get(orderNum); 247 if (o != null){ 248 bigDecimal = bigDecimal.subtract(o); 249 } 250 if (record == null) { 251 System.out.println("delete error;"); 252 } else { 253 order.delARecordByOrderNum(orderNum); 254 } 255 } 256 } 257 // 处理订单记录 258 else if (splitInput.length == 4) { 259 if(!splitInput[0].equals("table")){ 260 int orderNum = Integer.parseInt(splitInput[0]); 261 String dishName = splitInput[1]; 262 int portion = Integer.parseInt(splitInput[2]); 263 int num = Integer.parseInt(splitInput[3]); 264 Record record = order.addARecord(orderNum, dishName, portion, num); 265 if (record.dish == null) { 266 System.out.println(dishName + " does not exist"); 267 } else { 268 long totalPrice = record.getPrice() * num; 269 BigDecimal bigDecimal1 = BigDecimal.valueOf(totalPrice); 270 number.put(orderNum,bigDecimal1); 271 bigDecimal = bigDecimal.add(bigDecimal1); 272 System.out.println(orderNum + " " + dishName + " " + totalPrice); 273 } 274 } 275 else {//获取桌数,和时间 276 Table.tabletime(splitInput); 277 } 278 } 279 // 处理删除记录 280 else if (splitInput[1].equals("delete")) { 281 int orderNum = Integer.parseInt(splitInput[0]); 282 283 Record record = order.findRecordByNum(orderNum); 284 if (record == null) { 285 System.out.println("delete error"); 286 } else { 287 order.delARecordByOrderNum(orderNum); 288 } 289 } 290 input = scanner.nextLine(); 291 if (input.equals("end")){ 292 break; 293 } 294 } 295 scanner.close(); 296 System.out.print(bigDecimal.setScale(1, BigDecimal.ROUND_HALF_UP).intValue()); 297 } 298 }
类图如下:
题目的分析如下:
从程序设计角度来看,可以将这个题目分解为以下几个步骤:
1. 设计类和数据结构:需要设计菜品类(Dish)、菜谱类(Menu)、点菜记录类(Record)和订单类(Order)来组织数据和逻辑。菜品类包含菜品名称、基础价格和计算价格的方法。菜谱类包含菜品数组,可以根据菜名进行查找和添加。点菜记录类包含序号、菜品、份额和计价方法。订单类包含订单上的每一道菜的记录,可以添加、删除和计算总价。
2. 定义输入输出格式:根据题目要求,定义菜单、订单和代点菜信息的输入格式,以及输出每一桌的订单记录处理信息和总价的格式。
3. 解析输入:根据输入格式,逐行读取输入,并解析每一行的内容,将相关信息存储到对应的对象中。
4. 计算每一桌的订单记录和总价:遍历每一桌的订单记录和代点菜信息,根据菜谱中的菜品信息计算价格,考虑不同时段的折扣,并存储计算结果。
5. 输出结果:按照输入的先后顺序,依次输出每一桌的订单记录处理信息和总价的格式,包括桌号、订单记录和总价。
总体来说,需要设计合适的类和数据结构来组织数据,编写解析输入的逻辑,实现价格计算和折扣计算的方法,以及格式化输出结果的代码。分解问题,按步骤实现,可以更好地完成这个题目的设计和编写。
第五次大作业:
菜单4
1 import java.time.DayOfWeek; 2 import java.time.LocalDate; 3 import java.time.LocalTime; 4 import java.time.format.DateTimeParseException; 5 import java.util.regex.Matcher; 6 import java.util.regex.Pattern; 7 import java.util.*; 8 9 class Dish { 10 String name; 11 int unit_price; 12 public long getPrice(int portion) { 13 double price = unit_price; 14 if (portion == 2) { 15 price *= 1.5; 16 } else if (portion == 3) { 17 price *= 2; 18 } 19 return Math.round(price); 20 } 21 } 22 23 class SpecialDish { 24 Dish[] d = new Dish[100]; 25 int length = 0; 26 int totalSpecialPrice = 0; 27 int num = 0; 28 29 public void addDish(Menu m, String dishName, String portion, String count) { 30 d[length] = new Dish(); 31 d[length].name = dishName; 32 d[length].unit_price = (int) (m.searchDish(dishName).getPrice(Integer.parseInt(portion)) * Integer.parseInt(count)); 33 length++; 34 } 35 36 public int searchPrice(String dishName) { 37 for (Dish dish : d) { 38 if (dish.name.equals(dishName)) { 39 return dish.unit_price; 40 } 41 } 42 return 0; 43 } 44 45 public int getSpecialPrice() { 46 for (int i = 0; d[i] != null; i++) { 47 totalSpecialPrice += d[i].unit_price; 48 } 49 return totalSpecialPrice; 50 } 51 } 52 53 class Menu { 54 static Dish[] dishes = new Dish[100]; 55 int dishCount = 0; 56 public static Dish searchDish(String dishName) { 57 for (Dish dish : dishes) { 58 if (dish != null && dish.name.equals(dishName)) { 59 return dish; 60 } 61 } 62 return null; 63 } 64 Dish addDish(String dishName,int unit_price){ 65 Dish dish = new Dish(); 66 dish.name = dishName; 67 dish.unit_price = unit_price; 68 dishCount++; 69 return dish; 70 } 71 72 public int indexOfDish(String dishName,int dishAmount) { 73 Menu menu = new Menu(); 74 for (int i = 0; i < dishAmount; i++) { 75 if (menu.dishes[i].name.equals(dishName)) { 76 return i; 77 } 78 } 79 return -1; 80 } 81 } 82 class Record { 83 int orderNum; 84 Dish dish = new Dish(); 85 int num = 0; 86 int portion; 87 public long getPrice() { 88 if(dish != null) 89 return dish.getPrice(portion)*num; 90 else return 0; 91 } 92 } 93 class Order { 94 Record[] records = new Record[100]; 95 int count = 0; 96 97 int sum; 98 void addARecord(int orderNum,String dishName,int portion,int num){ 99 records[count] = new Record(); 100 records[count].dish.name = dishName; 101 records[count].orderNum = orderNum; 102 records[count].portion = portion; 103 records[count].num = num; 104 count++; 105 } 106 int getTotalPrice(){ 107 return sum; 108 } 109 long delARecordByOrderNum(int orderNum){ 110 if(orderNum>count||orderNum<=0){ 111 return 0; 112 }else { 113 return records[orderNum - 1].getPrice(); 114 } 115 } 116 public Record findRecordByNum(int orderNum) { 117 for (Record record : records) { 118 if (record != null && record.orderNum == orderNum) { 119 return record; 120 } 121 } 122 return null; 123 } 124 } 125 class Table { 126 int tableNum; 127 String Date; 128 String tableTime; 129 public Table() { 130 } 131 132 public Table(String tableNum, String date, String tableTime) { 133 this.tableNum = Integer.parseInt(tableNum); 134 this.Date = date; 135 this.tableTime = tableTime; 136 } 137 138 public static boolean isDateValid(String date1) { 139 try { 140 // 解析日期字符串 141 LocalDate.parse(date1); 142 return true; // 如果解析成功,则日期合法 143 } catch (DateTimeParseException e) { 144 return false; // 如果解析失败,则日期非法 145 } 146 } 147 148 public static boolean isWorkingDay(String dateString) { 149 Pattern pattern = Pattern.compile("(\\d+)/(\\d+)/(\\d+)"); 150 Matcher matcher = pattern.matcher(dateString); 151 152 if (matcher.matches()) { 153 int year = Integer.parseInt(matcher.group(1)); 154 int month = Integer.parseInt(matcher.group(2)); 155 int day = Integer.parseInt(matcher.group(3)); 156 157 LocalDate date = LocalDate.of(year, month, day); 158 DayOfWeek dayOfWeek = date.getDayOfWeek(); 159 160 return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY; 161 } 162 163 return false; // 日期格式不正确 164 } 165 166 //判断是否在周末营业时间 167 public static boolean isWithinTimeRange(String timeString) { 168 Pattern pattern = Pattern.compile("(\\d+)/(\\d+)/(\\d+)"); 169 Matcher matcher = pattern.matcher(timeString); 170 171 if (matcher.matches()) { 172 int hour = Integer.parseInt(matcher.group(1)); 173 int minute = Integer.parseInt(matcher.group(2)); 174 int seconds = Integer.parseInt(matcher.group(3)); 175 176 LocalTime time = LocalTime.of(hour, minute, seconds); 177 LocalTime startTime = LocalTime.of(9, 30); 178 LocalTime endTime = LocalTime.of(21, 30); 179 180 return !time.isBefore(startTime) && !time.isAfter(endTime); 181 } 182 return false; // 日期格式不正确 183 } 184 185 //判断是否在工作日中午营业时间 186 public static boolean isWithinTimeRange1(String timeString) { 187 Pattern pattern = Pattern.compile("(\\d+)/(\\d+)/(\\d+)"); 188 Matcher matcher = pattern.matcher(timeString); 189 190 if (matcher.matches()) { 191 int hour = Integer.parseInt(matcher.group(1)); 192 int minute = Integer.parseInt(matcher.group(2)); 193 int seconds = Integer.parseInt(matcher.group(3)); 194 195 LocalTime time = LocalTime.of(hour, minute, seconds); 196 LocalTime startTime = LocalTime.of(10, 30); 197 LocalTime endTime = LocalTime.of(14, 30); 198 199 return !time.isBefore(startTime) && !time.isAfter(endTime); 200 } 201 return false; // 日期格式不正确 202 } 203 204 //判断是否在工作日晚上营业时间 205 public static boolean isWithinTimeRange2(String timeString) { 206 Pattern pattern = Pattern.compile("(\\d+)/(\\d+)/(\\d+)"); 207 Matcher matcher = pattern.matcher(timeString); 208 209 if (matcher.matches()) { 210 int hour = Integer.parseInt(matcher.group(1)); 211 int minute = Integer.parseInt(matcher.group(2)); 212 int seconds = Integer.parseInt(matcher.group(3)); 213 214 LocalTime time = LocalTime.of(hour, minute, seconds); 215 LocalTime startTime = LocalTime.of(17, 0); 216 LocalTime endTime = LocalTime.of(20, 30); 217 218 return !time.isBefore(startTime) && !time.isAfter(endTime); 219 } 220 return false; // 日期格式不正确 221 } 222 Order order = new Order(); 223 float discount = -1; 224 225 void setDiscount(){ 226 if(isWorkingDay(Date))//工作日 227 { 228 if(isWithinTimeRange2(tableTime)) 229 discount =0.8F; 230 else if(isWithinTimeRange1(tableTime)) 231 discount =0.6F; 232 } 233 else 234 { 235 if(isWithinTimeRange(tableTime)) 236 discount = 1.0F; 237 } 238 } 239 float getDiscount(){ 240 return discount; 241 } 242 } 243 244 class default_expression{ 245 public static void wrong_fromat(){ 246 System.out.println("wrong format"); 247 } 248 public static void num_out_of_range(int num,int count){//份数超出范围 249 System.out.println(num + " num out of range " + count); 250 } 251 public static void portion_out_of_range(int num,int count){//份数超出范围 252 System.out.println(num + " portion out of range " + count); 253 } 254 255 public static void delect_deduplication(String count){//份数超出范围 256 System.out.println("deduplication :" + count); 257 } 258 } 259 260 public class test_order { 261 public static void main(String[] args) { 262 Scanner input = new Scanner(System.in); 263 Menu menu = new Menu(); 264 Table[] tables = new Table[10]; 265 int dishAmount = 0; 266 int orderAmount = 0; 267 Dish dish; 268 int tableAmount = 0; 269 int count; 270 String[] temp; 271 int str1, str2, str3, str4, str5; 272 while (true) { 273 String string = input.nextLine(); 274 temp = string.split(" "); 275 if (string.equals("end")) 276 break; 277 count = temp.length; 278 if (count == 2) { 279 if (temp[1].equals("delete")) { 280 str1 = Integer.parseInt(temp[0]); 281 if (tables[tableAmount].order.delARecordByOrderNum(str1) == 0) { 282 System.out.println("delete error;"); 283 } else { 284 long c = tables[tableAmount].order.delARecordByOrderNum(str1); 285 tables[tableAmount].order.sum -= c; 286 } 287 } else { 288 str2 = Integer.parseInt(temp[1]); 289 int existingIndex = menu.indexOfDish(temp[0],dishAmount); 290 if (existingIndex != -1) { 291 menu.dishes[existingIndex].unit_price = str2; 292 } else { 293 menu.dishes[dishAmount] = menu.addDish(temp[0], str2); 294 dishAmount++; 295 } 296 } 297 } else if (count == 3) { 298 if(temp[2].equals("T")){ 299 str2 = Integer.parseInt(temp[1]); 300 int existingIndex = menu.indexOfDish(temp[0],dishAmount); 301 if (existingIndex != -1) { 302 menu.dishes[existingIndex].unit_price = str2; 303 } else { 304 menu.dishes[dishAmount] = menu.addDish(temp[0], str2); 305 dishAmount++; 306 } 307 } 308 } else if (count == 4) { 309 if (temp[0].equals("table")){ 310 tableAmount++; 311 orderAmount = 0; 312 tables[tableAmount] = new Table(temp[1], temp[2], temp[3]); 313 tables[tableAmount].setDiscount(); 314 System.out.println("table " + temp[1] + ": "); 315 } else { 316 str3 = Integer.parseInt(temp[0]); 317 str4 = Integer.parseInt(temp[2]); 318 str5 = Integer.parseInt(temp[3]); 319 tables[tableAmount].order.addARecord(str3, temp[1],str4 , str5); 320 dish = menu.searchDish(temp[1]); 321 if(dish==null){ 322 System.out.println(temp[1]+" does not exist"); 323 } 324 if (dish != null) { 325 if(str5>15) {default_expression.num_out_of_range(str3,str5); }//份数超出范围 326 else if(str5<=0){default_expression.wrong_fromat(); } 327 else if (str4 != 1 && str4 != 2 && str4 != 3) { 328 default_expression.portion_out_of_range(str3,str4); 329 } else { 330 tables[tableAmount].order.records[orderAmount].dish = dish; 331 long a = tables[tableAmount].order.records[orderAmount].getPrice(); 332 System.out.println(tables[tableAmount].order.records[orderAmount].orderNum + " " + dish.name + " " + a); 333 tables[tableAmount].order.sum += a; 334 } 335 } 336 orderAmount++; 337 } 338 } 339 else if (count == 5){ 340 str1 = Integer.parseInt(temp[1]); 341 str2 = Integer.parseInt(temp[3]); 342 str3 = Integer.parseInt(temp[4]); 343 tables[tableAmount].order.addARecord(str1, temp[2], str2, str3); 344 dish = menu.searchDish(temp[2]); 345 if(dish==null){ 346 System.out.println(temp[2]+" does not exist"); 347 } 348 if (dish != null){ 349 tables[tableAmount].order.records[orderAmount].dish = dish; 350 long price = tables[tableAmount].order.records[orderAmount].getPrice(); 351 System.out.println(temp[1] + " table " + tables[tableAmount].tableNum + " pay for table " + temp[0] + " " + price); 352 tables[tableAmount].order.sum += price; 353 } 354 orderAmount++; 355 } 356 } 357 for(int i = 1; i < tableAmount + 1; i++){ 358 if(tables[i].getDiscount()>0){ 359 System.out.println("table " + tables[i].tableNum + ": "+ tables[i].order.getTotalPrice() + " " +Math.round(tables[i].order.getTotalPrice()*tables[i].getDiscount())); 360 } 361 else System.out.println("table " + tables[i].tableNum + " out of opening hours"); 362 } 363 } 364 }
类图如下:
题目的分析如下:
从程序设计的角度来看,可以将这个题目分解为以下几个步骤:
1. 定义类和数据结构:需要定义菜品类(Dish)、菜单类(Menu)、点菜记录类(Record)、订单类(Order)和桌号类(Table)用于组织数据和逻辑。菜品类包含菜品名称、基础价格和特色菜标识。菜单类包含菜品数组,提供查找菜品和添加菜品的方法。点菜记录类包含序号、菜品、份额、份数等信息,以及计算价格的方法。订单类包含订单上的所有点菜记录,提供添加、删除和计算总价的方法。桌号类用于存储桌号和时间信息。
2. 设计输入输出格式:根据题目要求,定义菜单、订单和代点菜信息的输入格式,以及每桌订单记录处理信息和总价的输出格式。
3. 解析输入:按照输入格式,逐行读取输入内容,并解析每一行的信息,将相关信息存储到对应的对象中。
4. 计算每一桌的订单记录和总价:根据订单中的点菜记录和代点菜信息,结合菜谱中的菜品信息,计算每一桌的订单记录的价格,并计算桌上所有菜品的总价。
5. 考虑折扣和时间范围:根据当前时间和营业时间的判断,对每一桌的总价进行折扣计算。
6. 输出结果:按照输入先后顺序,依次输出每一桌的订单记录处理信息和总价。将输出格式化为要求的格式,包括桌号、订单记录和总价。
在设计程序时,需要合理地组织类和数据结构,编写解析输入的逻辑,实现价格计算和折扣计算的方法,以及输出结果的代码。需要注意处理各种异常情况,包括重复删除记录、代点菜桌号不存在、份额和数量超过范围、时间超出范围等情况,对应输出相应的错误提示信息。分解问题,逐步实现,能够更好地完成题目的设计和编写。
第六次大作业:
菜单5
1 import java.util.*; 2 import java.text.ParseException; 3 import java.text.SimpleDateFormat; 4 5 public class order5 { 6 public static void main(String[] args) throws ParseException { 7 Menu menu = new Menu(); 8 // 读入菜单信息 9 Scanner sc = new Scanner(System.in); 10 String input = sc.nextLine(); 11 while (!input.startsWith("table")) { 12 String[] input_str = input.split(" "); 13 String name = input_str[0]; 14 try { 15 if (input_str.length == 2) { 16 int unit_price = Integer.parseInt(input_str[1]); 17 18 menu.addDish(name, unit_price); 19 } else if (input_str.length == 4 && input.endsWith("T")) { 20 String type = input_str[1]; 21 int unit_price = Integer.parseInt(input_str[2]); 22 menu.addDish(name, unit_price, type); 23 } else { 24 throw new IllegalArgumentException("wrong format"); 25 } 26 } catch (Exception e) { 27 System.out.println(e.getMessage()); 28 } 29 input = sc.nextLine(); 30 } 31 ArrayList<Table> tables = new ArrayList<>(); 32 ArrayList<String> names = new ArrayList<>(); 33 // 读入订单信息 34 int tableId = 0; 35 String name; 36 String phone ; 37 Date date ; 38 Date time ; 39 boolean legaltime = true; 40 boolean legalformat = true; 41 String orderLine = input; 42 while (!orderLine.equals("end")) { 43 String[] orderInfo = orderLine.split(" "); 44 // 解析桌号标识 45 if (orderLine.startsWith("table")) { 46 String regex = "^1(80|81|89|33|35|36)\\d{8}$"; 47 tableId = Integer.parseInt(orderInfo[1]); 48 name = orderInfo[3]; 49 phone = orderInfo[4]; 50 // First check for name and phone legality 51 if (name.length() > 10 || !phone.matches(regex)) { 52 System.out.println("wrong format"); 53 orderLine = sc.nextLine(); 54 legalformat = false; 55 continue; 56 } 57 try { 58 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); 59 SimpleDateFormat timeFormat = new SimpleDateFormat("HH/mm/ss"); 60 // Then parse date and time 61 date = dateFormat.parse(orderInfo[5]); 62 time = timeFormat.parse(orderInfo[6]); 63 Table table = new Table(tableId, name, phone, date, time); 64 tables.add(table); 65 if (!names.contains(name)) { 66 names.add(name); 67 } 68 // Check for table opening hours 69 if (table.getCoefficient(true) == 0) { 70 System.out.println("table " + table.tableId + " out of opening hours"); 71 legaltime = false; 72 } else { 73 System.out.println(table.printId()); 74 } 75 } catch (Exception e) { 76 System.out.println("wrong format"); 77 legalformat = false; 78 } 79 } else { 80 if (legalformat) { 81 int orderNum; 82 try { 83 orderNum = Integer.parseInt(orderInfo[0]); 84 } catch (Exception e) { 85 System.out.println("wrong format"); 86 orderLine = sc.nextLine(); 87 continue; 88 } 89 Table currentTable = tables.get(tableId - 1); 90 String dishName; 91 Dish dish; 92 Record record = null; 93 if (orderLine.endsWith("delete")) { 94 if (!currentTable.delRecordByOrderNum(orderNum)) { 95 System.out.println("delete error"); 96 } 97 return; 98 } 99 // Check for proper length of orderInfo. 100 if (orderInfo.length < 4 || orderInfo.length > 6) { 101 System.out.println("wrong format"); 102 return; 103 } 104 dishName = orderInfo[1]; 105 dish = menu.searchDish(dishName); 106 if (dish == null) { 107 System.out.println(dishName + " does not exist"); 108 orderLine = sc.nextLine(); 109 continue; 110 } 111 if (orderInfo.length == 4) { 112 record = new Record(tableId, orderNum, dish, 113 Integer.parseInt(orderInfo[2]), Integer.parseInt(orderInfo[3])); 114 currentTable.addRecord(record); 115 } else if (orderInfo.length == 5) { 116 record = new Record(tableId, orderNum, dish, 117 Integer.parseInt(orderInfo[2]), Integer.parseInt(orderInfo[3]), 118 Integer.parseInt(orderInfo[4])); 119 currentTable.addRecord(record); 120 } else { 121 int givenId = Integer.parseInt(orderInfo[1]); 122 record = new Record(givenId, orderNum, dish, Integer.parseInt(orderInfo[3]), Integer.parseInt(orderInfo[4]), Integer.parseInt(orderInfo[5])); 123 currentTable.addRecord(record); 124 record = new Record(givenId, orderNum, dish, Integer.parseInt(orderInfo[3]), 0, Integer.parseInt(orderInfo[5])); 125 tables.get(givenId - 1).addRecord(record); 126 } 127 if (legaltime) { 128 System.out.println(record.print(tableId)); 129 } 130 } 131 } 132 // 读入下一个桌号标识 133 orderLine = sc.nextLine(); 134 } 135 sc.close(); 136 for (Table table : tables) { 137 if (table.flag && table.getTotalPrice() != 0) { 138 System.out.println(table.str()); 139 } 140 } 141 names.sort(Comparator.naturalOrder()); 142 for (String costumName : names) { 143 int sum = 0; 144 String costumPhone = null; 145 for (Table table : tables) { 146 if (table.name.equals(costumName)) { 147 sum += table.getCheckedPrice(); 148 costumPhone = table.phone; 149 } 150 } 151 if (sum != 0) System.out.println(costumName + " " + costumPhone + " " + sum); 152 } 153 } 154 } 155 156 class Dish { 157 public String name; 158 public int unit_price; 159 public String type; 160 public Dish(String name, int unit_price, String type) { 161 this.name = name; 162 this.unit_price = unit_price; 163 this.type = type; 164 } 165 public Dish(String name, int unit_price) { 166 this.name = name; 167 this.unit_price = unit_price; 168 } 169 170 public void setName(String name) { 171 this.name = name; 172 } 173 public String getName() { 174 return name; 175 } 176 177 public void setUnit_price(int unit_price) { 178 this.unit_price = unit_price; 179 } 180 public int getUnit_price() { 181 return unit_price; 182 } 183 184 public void setType(String type) { 185 this.type = type; 186 } 187 public String getType() { 188 return type; 189 } 190 @Override 191 public String toString() { 192 return name; 193 } 194 } 195 class Menu { 196 public ArrayList<Dish> dishs = new ArrayList<>(); 197 Dish searchDish(String dishName) { 198 HashMap<String, Dish> dishMap = new HashMap<>(); 199 for (Dish dish : dishs) { 200 dishMap.put(dish.name, dish); 201 } 202 return dishMap.get(dishName); 203 } 204 205 void addDish(String dishName, int unit_price) { 206 dishs.add(new Dish(dishName, unit_price)); 207 } 208 void addDish(String dishName, int unit_price, String type) { 209 dishs.add(new Dish(dishName, unit_price, type)); 210 } 211 } 212 class Record { 213 int orderNum; 214 Dish dish; 215 int portion; 216 int quantity; 217 int level; 218 boolean flag; 219 int givenId; 220 boolean check_level() { 221 boolean result; 222 switch (dish.type) { 223 case "川菜": 224 result = level <= 5 && level >= 0; 225 break; 226 case "晋菜": 227 result = level <= 4 && level >= 0; 228 break; 229 case "浙菜": 230 result = level <= 3 && level >= 0; 231 break; 232 default: 233 result = true; 234 break; 235 } 236 return result; 237 } 238 public Record(int givenID, int orderNum, Dish dish, int portion, int quantity) { 239 this.orderNum = orderNum; 240 this.dish = dish; 241 this.portion = portion; 242 this.quantity = quantity; 243 this.level = -1; 244 this.flag = true; 245 this.givenId = givenID; 246 } 247 public Record(int givenId, int orderNum, Dish dish, int level, int portion, int quantity) { 248 this.orderNum = orderNum; 249 this.dish = dish; 250 this.portion = portion; 251 this.quantity = quantity; 252 this.level = level; 253 this.flag = check_level(); 254 this.givenId = givenId; 255 } 256 int getPrice() { 257 if (!flag) 258 return 0; 259 double coefficient; 260 if (portion == 1) { 261 coefficient = 1; 262 } else if (portion == 2) { 263 coefficient = 1.5; 264 } else if (portion == 3) { 265 coefficient = 2; 266 } else { 267 coefficient = 0; 268 } 269 return (int) Math.round(dish.unit_price * coefficient) * quantity; 270 } 271 int getCheckedPrice(Double coefficient) { 272 return (int) Math.round(getPrice() * coefficient); 273 } 274 public String print(int tableId) { 275 if (flag && givenId == tableId) { 276 return orderNum + " " + dish.toString() + " " + getPrice(); 277 } else if (flag) { 278 return orderNum + " table " + tableId + " pay for table " + givenId + " " + getPrice(); 279 } else { 280 String result = ""; 281 if ("川菜".equals(dish.type)) { 282 result = "spicy num out of range :" + level; 283 } else if ("晋菜".equals(dish.type)) { 284 result = "acidity num out of range :" + level; 285 } else if ("浙菜".equals(dish.type)) { 286 result = "sweetness num out of range :" + level; 287 } 288 return result; 289 } 290 } 291 @Override 292 public String toString() { 293 return "Record [orderNum=" + orderNum + ", dish=" + dish + ", portion=" + portion + ", quantity=" + quantity 294 + ", level=" + level + ", flag=" + flag + ", givenId=" + givenId + "]"; 295 } 296 } 297 class Table { 298 ArrayList<Record> records = new ArrayList<>(); 299 int tableId; 300 String name; 301 String phone; 302 Date date; 303 Date time; 304 boolean flag; 305 int[] num = new int[100]; 306 public Table(int tableId, String name, String phone, Date date, Date time) { 307 this.name = name; 308 this.phone = phone; 309 this.date = date; 310 this.time = time; 311 this.tableId = tableId; 312 this.flag = true; 313 } 314 double getCoefficient(boolean Special) throws ParseException { 315 double coefficient = 0; 316 SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm"); 317 Calendar cal = Calendar.getInstance(); 318 cal.setTime(date); 319 int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); 320 // 值为true和false时的系数 321 double coefficientTrue = Special ? 0.7 : 0.8; 322 // business hours 323 if (dayOfWeek == 1 || dayOfWeek == 7) { 324 if (time.after(sdfTime.parse("9:29")) && time.before(sdfTime.parse("21:31"))) { 325 coefficient = 1; 326 } 327 } else { 328 if (time.after(sdfTime.parse("16:59")) && time.before(sdfTime.parse("20:31"))) { 329 coefficient = coefficientTrue; 330 } else if (time.after(sdfTime.parse("10:29")) && time.before(sdfTime.parse("14:31"))) { 331 coefficient = Special ? 0.7 : 0.6; 332 } 333 } 334 flag = coefficient != 0; 335 return coefficient; 336 } 337 int getTotalPrice() { 338 int sum = 0; 339 for (Record record : records) { 340 sum += record.getPrice(); 341 } 342 return sum; 343 } 344 int getCheckedPrice() throws ParseException { 345 int sum = 0; 346 for (Record record : records) { 347 sum += record.getCheckedPrice(getCoefficient(record.level != -1)); 348 } 349 return sum; 350 } 351 String getAveLevel(String type) { 352 String[] spicy = { "不辣", "微辣", "稍辣", "辣", "很辣", "爆辣" }; 353 String[] acidity = { "不酸", "微酸", "稍酸", "酸", "很酸" }; 354 String[] sweetness = { "不甜", "微甜", "稍甜", "甜" }; 355 double sum = 0, num = 0; 356 for (Record record : records) { 357 if (Objects.equals(record.dish.type, type) && record.flag && tableId == record.givenId) { 358 num += record.quantity; 359 sum += record.level * record.quantity; 360 } 361 } 362 if (num == 0) { return ""; } 363 int ave = (int) Math.round(sum / num); 364 String result = " " + type + " " + (int) num + " "; 365 return type.equals("川菜") ? result + spicy[ave] : 366 type.equals("晋菜") ? result + acidity[ave] : 367 type.equals("浙菜") ? result + sweetness[ave] : 368 null; 369 } 370 371 public boolean ifExistTableNum(int tableNum){ 372 for (int index : num) { 373 if (index == tableNum) { 374 return true; 375 } 376 } 377 return false; 378 } 379 void addRecord(Record record) { 380 records.add(record); 381 } 382 boolean delRecordByOrderNum(int orderNum) { 383 return records.removeIf(record -> record.orderNum == orderNum); 384 } 385 public String printId() { 386 return "table " + tableId + ": "; 387 } 388 public String str() throws ParseException { 389 String chuan = getAveLevel("川菜"); 390 String jin = getAveLevel("晋菜"); 391 String zhe = getAveLevel("浙菜"); 392 String baseStr = "table " + tableId + ": " + getTotalPrice() + " " + getCheckedPrice(); 393 boolean noAveLevel = Objects.equals(chuan, "") && Objects.equals(jin, "") && Objects.equals(zhe, ""); 394 return noAveLevel ? baseStr + " " : baseStr + chuan + jin + zhe; 395 } 396 }
类图如下:
题目的分析如下:
这一题我并没有拿满分,代点菜的功能没能加上去,因为我之前写代码太乱了,这个完全又是重新写的一个,好累TAT,我真的好菜,每次写java大作业都是折磨QAQ
从程序设计的角度来看,我们可以将这个题目分解为以下几个步骤:
1. 定义类和数据结构:需要定义菜品类(Dish)、菜单类(Menu)、点菜记录类(Record)、订单类(Order)、桌号类(Table)和客户类(Customer)用于组织数据和逻辑。菜品类包含菜品名称、基础价格、口味类型和特色菜标识。菜单类包含菜品数组,提供查找菜品和添加菜品的方法。点菜记录类包含序号、菜品、口味度、份额、份数等信息,以及计算价格和口味度平均值的方法。订单类包含订单上的所有点菜记录以及对应的桌号和客户信息,提供添加、删除和计算总价的方法。桌号类用于存储桌号和时间信息。客户类包含姓名和手机号信息。
2. 设计输入输出格式:根据题目要求,定义菜单、订单和代点菜信息的输入格式,以及每桌订单记录处理信息、总价和口味度平均值的输出格式。
3. 解析输入:按照输入格式,逐行读取输入内容,并解析每一行的信息,将相关信息存储到对应的对象中,包括菜单、订单、代点菜和客户信息。
4. 计算每一桌的订单记录和总价:根据订单中的点菜记录和代点菜信息,结合菜谱中的菜品信息,计算每一桌的订单记录的价格,并计算桌上所有菜品的总价。同时,计算口味度的累计值和总份数,以及口味度的平均值。
5. 考虑折扣和时间范围:根据当前时间和营业时间的判断,对每一桌的总价进行折扣计算。
6. 输出结果:按照输入先后顺序,依次输出每一桌的订单记录处理信息、总价和口味度平均值。将输出格式化为要求的格式,包括桌号、订单记录、总价和口味度平均值。同时,根据客户信息统计并输出每位客户的总支付金额。
在设计程序时,需要合理地组织类和数据结构,编写解析输入的逻辑,实现价格计算、口味度计算和折扣计算的方法,以及输出结果的代码。需要注意处理各种异常情况,包括重复删除记录、代点菜桌号不存在、份额和数量超过范围、时间超出范围等情况,对应输出相应的错误提示信息。分解问题,逐步实现,能够更好地完成题目的设计和编写。
期中考试
最后一个关于接口的编程题:
1 import java.util.ArrayList; 2 import java.util.Scanner; 3 import java.util.Comparator; 4 5 abstract class Shape implements Comparable<Shape> { 6 public abstract double getArea(); 7 8 @Override 9 public int compareTo(Shape o) { 10 return Double.compare(this.getArea(), o.getArea()); 11 } 12 } 13 14 class Point { 15 double x; 16 double y; 17 18 public Point(double x, double y) { 19 this.x = x; 20 this.y = y; 21 } 22 } 23 24 class Rectangle extends Shape { 25 Point topLeftPoint; 26 Point lowerRightPoint; 27 28 public Rectangle(Point topLeftPoint, Point lowerRightPoint) { 29 this.topLeftPoint = topLeftPoint; 30 this.lowerRightPoint = lowerRightPoint; 31 } 32 33 public double getArea() { 34 double width = this.lowerRightPoint.x - this.topLeftPoint.x; 35 double height = this.topLeftPoint.y - this.lowerRightPoint.y; 36 return Math.abs(width * height); // 使用绝对值确保面积为正数 37 } 38 } 39 40 class Circle extends Shape { 41 double r; // 圆的半径 42 43 public Circle(double r) { 44 this.r = r; 45 } 46 47 public double getArea() { // 面积 48 return Math.PI * r * r; 49 } 50 } 51 52 public class test { 53 public static void main(String[] args) { 54 Scanner input = new Scanner(System.in); 55 ArrayList<Shape> list = new ArrayList<>(); 56 57 int choice = input.nextInt(); 58 59 while (choice != 0) { 60 switch (choice) { 61 case 1:// 已测试.Circle 62 double radius = input.nextDouble(); 63 if (radius <= 0) { 64 System.out.println("Wrong Format"); 65 } else { 66 Shape circle = new Circle(radius); 67 list.add(circle); 68 } 69 break; 70 case 2:// 已测试.Rectangle 71 double x1 = input.nextDouble(); 72 double y1 = input.nextDouble(); 73 double x2 = input.nextDouble(); 74 double y2 = input.nextDouble(); 75 76 Point leftTopPoint = new Point(x1, y1); 77 Point lowerRightPoint = new Point(x2, y2); 78 Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint); 79 list.add(rectangle); 80 break; 81 } 82 choice = input.nextInt(); 83 } 84 85 list.sort(Comparator.naturalOrder());//正向排序 86 87 for (int i = 0; i < list.size(); i++) { 88 System.out.print(String.format("%.2f", list.get(i).getArea()) + " "); 89 } 90 } 91 }
类图如下:
总结
面向对象设计是一种抽象和建模的方法,能够将复杂问题分解为更小、更可管理的部分。在使用Java语言进行面向对象设计时,以下几个方面值得特别注意和学习:
-
类和对象的设计:类是面向对象设计的基本单位,它具有属性(数据)和方法(行为)。在设计类时,需要关注类的职责和功能,确保类具有高内聚和低耦合的特性。合理选择和设计类的属性和方法,使其能够描述对象的状态和行为。同时,要注意类之间的关系,如继承、接口实现、组合等。通过合理的类和对象设计,能够更好地组织和管理代码,提高代码的可读性和可维护性。
-
封装和信息隐藏:封装是面向对象设计的核心原则之一,通过封装可以将数据和方法组合在一起,形成类的内部实现细节。封装可以隐藏内部细节,只暴露必要的接口给外部使用。在设计类时,要考虑属性的访问权限和方法的正确使用方式,以保证数据安全性和代码的可靠性。
-
继承和多态:继承是面向对象设计的另一个重要概念,它能够通过子类继承父类的属性和方法,并可以添加或修改自己的特性。通过合理使用继承,可以实现代码的复用,并能够体现出对象之间的关系("is-a"关系)。多态是继承的一种扩展,通过多态可以在程序运行时,根据实际对象的类型,选择正确的方法调用。对于继承和多态的使用,要考虑类之间的关系、方法的覆盖和重载,以及灵活使用接口和抽象类。
-
设计模式和代码重构:设计模式是一些解决特定问题的经验和经典方案的总结,能够提供可重用的解决方案。在面向对象设计中,学习和应用设计模式能够提高代码的质量和可维护性。同时,代码重构是改善现有代码的一种方式,它能够通过优化代码结构、提高代码的可读性和可维护性。学习并熟练使用设计模式和代码重构的技巧,有助于提高代码设计和编写的效率。
-
异常处理和错误处理:在面向对象设计中,异常处理是一种常见的行为,能够提高代码的容错性和健壮性。合理捕获和处理异常,能够避免程序的崩溃,并提供友好的错误提示信息。同时,可以针对不同的异常类型,进行适当的处理和恢复。在设计类和方法时,要考虑可能出现的异常情况,并提供相应的处理方式。
这几次的菜单系列题目的迭代真的是繁琐,对于我还没怎掌握到面向对象编写代码的精髓的来说,代码写的很乱,逻辑没有条理性,导致每次进行迭代的时候,我一般不会选择在前一次的主结构上修改,而是只保存了基本类结构,然后重新写结构和细节,好痛苦啊啊啊啊,每次写大作业真的好烦TAT,我的逻辑真的非常差,每次写结构真的想不清楚,感觉都不像面向对象设计,完全就是面向题目设计,希望后面的大作业不要太难,通过后面的学习能理解掌握一点面向对象设计的核心思想吧。