1.前言
自上次的博客又过去了一个多月,经过一段时间对Java的学习我们也迎来了期末考试了。这几次pta是期末前的最后几次pta,考察了菜单程序和课程程序,难度较之前有所提升,在下面分析一下。
2.设计与分析
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的基础上增加了部分内容,增加的内容用加粗字体标识。
注意不是菜单计价程序-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:
桌号时间超出营业范围。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 21/30/00
1 麻婆豆腐 3 1 2
2 油淋生菜 2 1
3 麻婆豆腐 2 3 2
end
输出样例1:
在这里给出相应的输出。例如:
table 1 out of opening hours
输入样例2:
一种口味的菜品。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 20/30/00
1 麻婆豆腐 2 1 2
2 油淋生菜 2 1
3 麻婆豆腐 2 3 2
end
输出样例2:
在这里给出相应的输出。例如:
table 1:
1 麻婆豆腐 24
2 油淋生菜 14
3 麻婆豆腐 48
table 1: 86 62 川菜 4 稍辣
tom 13605054400 62
输入样例3:
辣度值超出范围。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 18/30/00
1 麻婆豆腐 6 1 2
2 油淋生菜 1 1
3 麻婆豆腐 5 3 2
end
输出样例3:
在这里给出相应的输出。例如:
table 1:
spicy num out of range :6
2 油淋生菜 9
3 麻婆豆腐 48
table 1: 57 41 川菜 2 爆辣
tom 13605054400 41
输入样例4:
同一用户对应多桌菜。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 18/30/00
1 麻婆豆腐 1 1 2
2 油淋生菜 1 1
3 麻婆豆腐 2 2 2
table 2 : tom 13605054400 2023/5/6 18/30/00
1 麻婆豆腐 2 1 2
2 麻辣鸡丝 2 2
3 麻婆豆腐 2 1 1
end
输出样例4:
在这里给出相应的输出。例如:
table 1:
1 麻婆豆腐 24
2 油淋生菜 9
3 麻婆豆腐 36
table 2:
1 麻婆豆腐 24
2 麻辣鸡丝 30
3 麻婆豆腐 12
table 1: 69 49 川菜 4 稍辣
table 2: 66 66 川菜 3 稍辣
tom 13605054400 115
输入样例5:
多用户多桌菜。例如:
东坡肉 浙菜 25 T
油淋生菜 9
蜜汁灌藕 浙菜 10 T
刀削面 晋菜 10 T
醋浇羊肉 晋菜 30 T
麻婆豆腐 川菜 12 T
麻辣鸡丝 川菜 15 T
table 1 : tom 13605054400 2023/5/6 12/30/00
1 醋浇羊肉 4 1 1
3 刀削面 1 1 3
2 东坡肉 3 2 1
4 麻辣鸡丝 2 1 1
table 2 : jerry 18100334566 2023/5/1 12/30/00
1 醋浇羊肉 1 1 2
3 麻婆豆腐 2 2 1
4 麻辣鸡丝 2 3 3
table 3 : jerry 18100334566 2023/5/1 12/30/00
1 醋浇羊肉 2 1 1
3 蜜汁灌藕 1 1 2
2 东坡肉 2 2 1
4 麻辣鸡丝 5 1 1
end
输出样例5:
在这里给出相应的输出。例如:
table 1:
1 醋浇羊肉 30
3 刀削面 30
2 东坡肉 38
4 麻辣鸡丝 15
table 2:
1 醋浇羊肉 60
3 麻婆豆腐 18
4 麻辣鸡丝 90
table 3:
1 醋浇羊肉 30
3 蜜汁灌藕 20
2 东坡肉 38
4 麻辣鸡丝 15
table 1: 113 113 川菜 1 稍辣 晋菜 4 稍酸 浙菜 1 甜
table 2: 168 118 川菜 4 稍辣 晋菜 2 微酸
table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜
jerry 18100334566 191
tom 13605054400 113
输入样例6:
多用户多桌菜含代点菜。例如:
东坡肉 浙菜 25 T
油淋生菜 9
蜜汁灌藕 浙菜 10 T
刀削面 晋菜 10 T
醋浇羊肉 晋菜 30 T
麻婆豆腐 川菜 12 T
麻辣鸡丝 川菜 15 T
table 1 : tom 13605054400 2023/5/6 12/30/00
1 醋浇羊肉 4 1 1
3 刀削面 1 1 3
2 东坡肉 3 2 1
4 麻辣鸡丝 2 1 1
table 2 : jerry 18100334566 2023/5/1 12/30/00
1 1 醋浇羊肉 0 1 2
3 麻婆豆腐 2 2 1
4 麻辣鸡丝 2 3 3
table 3 : lucy 18957348763 2023/5/1 12/30/00
1 醋浇羊肉 2 1 1
3 蜜汁灌藕 1 1 2
2 东坡肉 2 2 1
4 麻辣鸡丝 5 1 1
end
输出样例6:
在这里给出相应的输出。例如:
table 1:
1 醋浇羊肉 30
3 刀削面 30
2 东坡肉 38
4 麻辣鸡丝 15
table 2:
1 table 2 pay for table 1 60
3 麻婆豆腐 18
4 麻辣鸡丝 90
table 3:
1 醋浇羊肉 30
3 蜜汁灌藕 20
2 东坡肉 38
4 麻辣鸡丝 15
table 1: 113 113 川菜 1 稍辣 晋菜 6 微酸 浙菜 1 甜
table 2: 168 118 川菜 4 稍辣
table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜
jerry 18100334566 118
lucy 18957348763 73
tom 13605054400 113
输入样例7:
错误的菜品记录和桌号记录,用户丢弃。例如:
东坡肉 25 T
油淋生菜 9
table 1 : tom 136050540 2023/5/1 12/30/00
2 东坡肉 3 2 1
end
输出样例7:
在这里给出相应的输出。例如:
wrong format
wrong format
代码如下
import java.util.regex.Pattern; import java.util.*; public class Main{ static CmdProcess cmdPro = new CmdProcess(); static View view = new View(); static boolean isLocked = false; public static void main(String[] args){ String command = ""; do{ command = view.input(); cmdProcess(command); }while(!command.equals("end")); return; } public static void cmdProcess(String command) { //分割指令 String[] values = command.split(" "); int commandId = cmdSort(command); if(isLocked && !(commandId == 2 || commandId == 0)) return; //以下为情况分辨不同类型指令 switch(commandId) { case 0:{ cmdPro.end(); }break; case 1:{ String dishName = values[0];//菜名 int unitPrice = Integer.parseInt(values[1]);//价格 cmdPro.inputMenu(dishName, unitPrice, 0); }break; case 2:{ int tableID = Integer.parseInt(values[1]);//桌号 String orderName = values[3]; String orderTel = values[4]; String date = values[5];//日期 String time = values[6];//时间 isLocked = !cmdPro.addTable(tableID, date, time, orderName, orderTel); }break; case 3:{ int orderNum = Integer.parseInt(values[0]);//序号 String dishName = values[1];//菜名 int portion= Integer.parseInt(values[2]);//份额 int num= Integer.parseInt(values[3]);//份数 cmdPro.orderDish(orderNum, dishName, portion, num); }break; case 4:{ int orderNum = Integer.parseInt(values[0]);//序号 cmdPro.deleteDish(orderNum); }break; case 5:{ int profitTableNum = Integer.parseInt(values[0]); int orderNum = Integer.parseInt(values[1]);//序号 String dishName = values[2];//菜名 int portion= Integer.parseInt(values[3]);//份额 int num= Integer.parseInt(values[4]); cmdPro.orderOthers(profitTableNum, orderNum, dishName, portion, num); }break; case 6:{ String dishName = values[0]; int tStyle = 0; String styleStr = values[1]; if(styleStr.equals("川菜")) tStyle = 1; else if(styleStr.equals("晋菜")) tStyle = 2; else if(styleStr.equals("浙菜")) tStyle = 3; else { cmdPro.unknowCmd(); break; } //价格 int unitPrice = Integer.parseInt(values[2]); cmdPro.inputMenu(dishName, unitPrice, tStyle); }break; case 7:{ int orderNum = Integer.parseInt(values[0]);//序号 String dishName = values[1];//菜名 int portion= Integer.parseInt(values[2]);//份额 int num= Integer.parseInt(values[3]);//份数 cmdPro.orderDish(orderNum, dishName, portion, num); }break; case 8:{ }break; default: cmdPro.unknowCmd(); } } public static int cmdSort(String command) { String[] patterns = { "^end$",//0 "^\\S+ [1-9]\\d*$",//1 "^table [1-9]\\d* : \\S+ (180|181|189|133|135|136)\\d{8} \\d{4}/\\d{1,2}/\\d{1,2} \\d{1,2}/\\d{1,2}/\\d{1,2}$",//2 "^[1-9]\\d* \\S+ \\d [1-9]\\d*$",//3 "^[1-9]\\d* delete$",//4 "^[1-9]\\d* [1-9]\\d* \\S+ \\d [1-9]\\d*$",//5 "^\\S+ \\S+ [1-9]\\d* T$",//6 "^[1-9]\\d* \\S+ \\d \\d [1-9]\\d*$",//7 "^[1-9]\\d* [1-9]\\d* \\S+ \\d \\d [1-9]\\d*$",//8 }; for(int i = 0; i < patterns.length; i++) { if(Pattern.matches(patterns[i], command)) return i; } return -1; } } class CmdProcess{ private View view = new View(); private Menu menu = Menu.getMenu(); private Order[] orders = new Order[0]; private Order currentOrder; private Table[] tables = new Table[0]; private Table currentTable; private int[] deletedNums = new int[0]; public void end() { for(Table table : this.tables) { int id = table.getId(); int price = table.getPrice(); int discountedPrice = table.getDiscountedPrice(); this.view.outputPrice(id, price, discountedPrice); } } public void inputMenu(String dishName, int unitPrice, int tStyle) { //菜谱信息与订单信息混合 if(this.orders.length > 0) { this.view.invalidDish(); return; } //超出范围 if(unitPrice <= 0 || unitPrice >= 300) { this.view.priceOut(dishName, unitPrice); return; } this.menu.addDish(dishName, unitPrice, tStyle); } public boolean addTable(int id, String date, String time, String orderName, String orderTel) { this.currentOrder = null; for(Order order : this.orders) { if(order.getName().equals(orderName) && order.getTel().equals(orderTel)) { this.currentOrder = order; break; } } if(this.currentOrder == null) { Order[] newOrders = new Order[this.orders.length + 1]; for(int i = 0; i < this.orders.length; i++) { newOrders[i] = this.orders[i]; } this.currentOrder = new Order(orderName, orderTel); newOrders[this.orders.length] = this.currentOrder; this.orders = newOrders; } if(id < 1 || id > 55) { this.view.tableIdOut(id); return false; } Table newTable = new Table(id, date, time, this.currentOrder); if(!newTable.getDate().checkInputValidityIgnoreYear() || !newTable.getTime().check()) { this.view.dateErr(id); return false; } if(!newTable.isValidTime()) { this.view.dateOut(); return false; } //不在营业时间 if(!newTable.isInOpeningTime()) { this.view.closingHour(id); return false; } //查找相同桌号 for(Table table : this.tables) { if(table.getId() == id) { if(table.isInTheSameTime(newTable)) { this.currentTable = table; this.view.outputTable(id); return true; } break; } } Table[] newTables = new Table[this.tables.length + 1]; for(int i = 0; i < this.tables.length; i++){ newTables[i] = this.tables[i]; } newTables[this.tables.length] = newTable; this.tables = newTables; this.currentTable = newTable; this.view.outputTable(id); return true; } public void orderDish(String command) { if(this.currentOrder == null) return; if(!Pattern.matches("^[1-9]\\d* \\S+ \\d [1-9]\\d*$", command)) { this.view.wrongFormat(); return; } String[] values = command.split(" "); int orderNum = Integer.parseInt(values[0]); String dishName = values[1];//菜名 int portion= Integer.parseInt(values[2]); int num= Integer.parseInt(values[3]); this.orderDish(orderNum, dishName, portion, num); } public void orderDish(int orderId, String dishName, int portion, int num) { if(this.currentOrder == null) return; //菜名不存在 if(this.menu.searchDish(dishName) == null){ this.view.notTheDish(dishName); return; } if(!this.menu.searchDish(dishName).hasPortion(portion)) { this.view.portionOut(orderId, portion); return; } if(num > 15 || num < 1) { this.view.numOut(orderId, num); return; } if(this.currentTable.getMaxOrderId() >= orderId) { this.view.seqErr(); return; } Record record = this.currentTable.addARecord(orderId, dishName, portion, num); this.view.outputRecord(record); } public void deleteDish(int orderNum) { for(int deletedNum : this.deletedNums) { if(deletedNum == orderNum) { this.view.dedu(orderNum); return; } } int length = this.deletedNums.length; int[] newDeleteNums = new int[length + 1]; for(int i = 0; i < length; i++) { newDeleteNums[i] = this.deletedNums[i]; } newDeleteNums[length] = orderNum; this.deletedNums = newDeleteNums; if(this.currentTable.findRecordByNum(orderNum) == null){ this.view.deleteErr(); return; } this.currentTable.delARecordByOrderNum(orderNum); } public void orderOthers(int othersId, int orderNum, String dishName, int portion, int num) { boolean hasId = false; for(Table table : this.tables) { if(table.getId() == othersId) { hasId = true; break; } } if(!hasId) { this.view.notTheTable(othersId); return; } } public void unknowCmd() { this.view.wrongFormat(); } } class View{ private Scanner input = new Scanner(System.in); public String input() { return this.input.nextLine(); } public void outputTable(int id) { System.out.println("table " + id + ": "); } public void outputRecord(Record record) { System.out.printf("%d %s %d\n", record.getOredrId(), record.getDish().getName(), record.getPrice()); } public void outputPrice(int id, int price, int discountedPrice) { System.out.println("table " + id + ": " + price + " " + discountedPrice); } public void deleteErr() { System.out.println("delete error"); } public void closingHour(int id) { System.out.println("table " + id + " out of opening hours"); } public void invalidDish() { System.out.println("invalid dish"); } public void dateErr(int id) { System.out.println(id + " date error"); } public void dedu(int index) { System.out.println("deduplication " + index); } public void notTheTable(int id) { System.out.println("Table number :" + id + " does not exist"); } public void notTheDish(String name) { System.out.println(name + " does not exist"); } public void portionOut(int index, int portion) { System.out.println(index + " portion out of range " + portion); } public void numOut(int index, int num) { System.out.println(index + " num out of range " + num); } public void tableIdOut(int id) { System.out.println(id + " table num out of range"); } public void priceOut(String name, int price) { System.out.println(name + " price out of range " + price); } public void dateOut() { System.out.println("not a valid time period"); } public void seqErr() { System.out.println("record serial number sequence error"); } public void wrongFormat() { System.out.println("wrong format"); } } class Dish { private String name; private int unit_price; public Dish(String name, int unitPrice){ this.name = name; this.unit_price = unitPrice; } public boolean hasPortion(int portion) { switch(portion) { case 1: return true; case 2: //if(this.isT) return false; return true; case 3: return true; default: return false; } } public int getPrice(int portion){ switch(portion){ case 1: return this.unit_price; case 2: return (int)(this.unit_price * 1.5 + 0.5); case 3: return this.unit_price * 2; default: return 0; } } public String getName(){ return this.name; } public void setUnitPrice(int unitPrice){ this.unit_price = unitPrice; } } class TDish extends Dish{ private int style = 0; public TDish(String name, int unitPrice, int style) { super(name, unitPrice); this.style = style; } public int getSytle() { return this.style; } } class Menu { private Dish[] dishs; private static Menu menu; private Menu(){ this.dishs = new Dish[0]; } public static Menu getMenu() { if(menu == null) menu = new Menu(); return menu; } public Dish searchDish(String dishName){ for(Dish dish : this.dishs){ if(dish.getName().compareTo(dishName) == 0){ return dish; } } return null; } public Dish addDish(String dishName, int unit_price, int tStyle){ Dish dish = this.searchDish(dishName); if(dish != null){ dish.setUnitPrice(unit_price); return dish; } Dish[] newDishs = new Dish[this.dishs.length + 1]; for(int i = 0; i < this.dishs.length; i++){ newDishs[i] = this.dishs[i]; } Dish newDish; if(tStyle == 0) { newDish = new Dish(dishName, unit_price); }else { newDish = new TDish(dishName, unit_price, tStyle); } newDishs[this.dishs.length] = newDish; this.dishs = newDishs; return newDish; } } class Record { private int orderId; private Dish d; private int portion; private int num; private int tasteLevel = 0; private DateUtil date; private TimeUtil time; public Record(DateUtil date, TimeUtil time, int orderId, String dishName, int portion,int num){ this.orderId = orderId; this.d = Menu.getMenu().searchDish(dishName); this.portion = portion; this.num = num; this.date = date; this.time = time; } public Record(DateUtil date, TimeUtil time, int orderId, String dishName, int portion,int num, int tasteLevel){ this.orderId = orderId; this.d = Menu.getMenu().searchDish(dishName); this.portion = portion; this.num = num; this.date = date; this.time = time; this.tasteLevel = tasteLevel; } public int getTasteLevel() { return this.tasteLevel; } public int getTStyle() { if(!(this.d instanceof TDish)) return 0; return ((TDish)this.d).getSytle(); } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public DateUtil getDate() { return this.date; } public TimeUtil getTime() { return this.time; } public int getPortion() { return portion; } public int getOredrId(){ return this.orderId; } public Dish getDish(){ return this.d; } public int getPrice(){ return this.d.getPrice(this.portion) * this.num; } public int getDiscountedPrice(){ return (int)(this.getPrice() * this.getDiscount() + 0.5); } public double getDiscount(){ int week = this.date.getWeek(); if(week >= 1 && week <= 5){ if(this.time.isBetween(new TimeUtil(17, 0, 0), new TimeUtil(20, 30, 0))) { //if(this.d.isT()) return 0.7; return 0.8; } if(this.time.isBetween(new TimeUtil(10, 30, 0), new TimeUtil(14, 30, 0))) { //if(this.d.isT()) return 0.7; return 0.6; } return -1; } if(this.time.isBetween(new TimeUtil(9, 30, 0), new TimeUtil(21, 30, 0))) return 1.0; return -1; } } class Order{ private String name = ""; private String tel = ""; private Table[] tables = new Table[0]; public Order(String name, String tel) { this.name = name; this.tel = tel; } public String getName() { return this.name; } public String getTel() { return this.tel; } public int getPrice() { int price = 0; for(Table table : this.tables) { price += table.getPrice(); } return price; } public Table[] getTables() { return this.tables; } public int getTablesCount() { return this.tables.length; } public void chooseTable(Table table) { Table[] newTables = new Table[this.tables.length + 1]; for(int i = 0; i < this.tables.length; i++) { newTables[i] = this.tables[i]; } newTables[this.tables.length] = table; this.tables = newTables; } } class Table { private Record[] records = new Record[0]; private Record[] profitRecords = new Record[0]; private DateUtil orderDate; private TimeUtil orderTime; private int id = 0; private Order master = null; private int givenPrice = 0; public Table(int id, String date, String time, Order master){ this.id = id; String[] dateData = date.split("/"); int year = Integer.parseInt(dateData[0]); int month = Integer.parseInt(dateData[1]); int day = Integer.parseInt(dateData[2]); this.orderDate = new DateUtil(year, month, day); String[] timeData = time.split("/"); int hour = Integer.parseInt(timeData[0]); int minute = Integer.parseInt(timeData[1]); int second = Integer.parseInt(timeData[2]); this.orderTime = new TimeUtil(hour, minute, second); this.master = master; } public Order getMaster() { return this.master; } public DateUtil getDate() { return this.orderDate; } public TimeUtil getTime() { return this.orderTime; } public int getId() { return this.id; } public Record[] getSimpleRecords() { Record[] records = new Record[0]; for(Record record : this.records) { boolean hasTheSame = false; for(Record rec : records) { if(record.getDish().getName().equals(rec.getDish().getName()) && record.getPortion() == rec.getPortion()) { rec.setNum(rec.getNum() + record.getNum()); hasTheSame = true; } } if(!hasTheSame) { Record[] newRecords = new Record[records.length + 1]; for(int i = 0; i < records.length; i++) { newRecords[i] = records[i]; } newRecords[records.length] = new Record(record.getDate(), record.getTime(), 0, record.getDish().getName(), record.getPortion(), record.getNum()); records = newRecords; } } return records; } public int getPrice(){ Record[] records = this.getSimpleRecords(); int priceSum = 0; for(Record record : records){ priceSum += record.getPrice(); } return priceSum + this.givenPrice; } public int getDiscountedPrice(){ Record[] records = this.getSimpleRecords(); int priceSum = 0; for(Record record : records){ priceSum += record.getDiscountedPrice(); } return priceSum + this.givenPrice; } public int getMaxOrderId() { int max = 0; for(Record record : this.records) { int orderId = record.getOredrId(); if(max < orderId) max = orderId; } return max; } public int getPepperyLevelAvg() { int count = 0; int levelSum = 0; for(Record record : this.records) { if(record.getTStyle() == 1) { levelSum += record.getTasteLevel(); count++; } } if(count == 0) return -1; return (int)(levelSum / count + 0.5); } public int getAcidLevelAvg() { int count = 0; int levelSum = 0; for(Record record : this.records) { if(record.getTStyle() == 2) { levelSum += record.getTasteLevel(); count++; } } if(count == 0) return -1; return (int)(levelSum / count + 0.5); } public int getSweetLevelAvg() { int count = 0; int levelSum = 0; for(Record record : this.records) { if(record.getTStyle() == 3) { levelSum += record.getTasteLevel(); count++; } } if(count == 0) return -1; return (int)(levelSum / count + 0.5); } public boolean isValidTime() { if(!this.orderDate.compareDates(new DateUtil(2022, 1, 1))) return false; if(this.orderDate.compareDates(new DateUtil(2024, 1, 1))) return false; return true; } public boolean isInOpeningTime() { int week = this.orderDate.getWeek(); if(week >= 1 && week <= 5){ if(this.orderTime.isBetween(new TimeUtil(17, 0, 0), new TimeUtil(20, 30, 0))) { return true; } if(this.orderTime.isBetween(new TimeUtil(10, 30, 0), new TimeUtil(14, 30, 0))) { return true; } return false; } if(this.orderTime.isBetween(new TimeUtil(9, 30, 0), new TimeUtil(21, 30, 0))) return true; return false; } public boolean isInTheSameTime(Table table) { if(!this.isInOpeningTime()) return false; if(!table.isInOpeningTime()) return false; if(!this.orderDate.equalTwoDates(table.getDate())) return false; int week = this.orderDate.getWeek(); if(week >= 1 || week <= 5) { boolean isThisInNoon = this.orderTime.isEarlyThan(new TimeUtil(16, 0, 0)); boolean isThatInNoon = table.getTime().isEarlyThan(new TimeUtil(16, 0, 0)); if(isThisInNoon == isThatInNoon) return true; return false; } if(this.orderTime.compareTo(orderTime) < 60 * 60) return true; return false; } public Record searchRecord(String dishName, int portion) { for(Record record : records) { if(record.getDish().getName().equals(dishName) && record.getPortion() == portion) { return record; } } return null; } public Record addARecord(int orderNum,String dishName,int portion,int num){ Record newRecord = new Record(this.orderDate, this.orderTime, orderNum, dishName, portion, num); Record[] newRecords = new Record[this.records.length + 1]; for(int i = 0; i < this.records.length; i++){ newRecords[i] = this.records[i]; } newRecords[this.records.length] = newRecord; this.records = newRecords; return newRecord; } public Record addAProfitRecord(int orderNum,String dishName,int portion,int num){ Record newRecord = new Record(this.orderDate, this.orderTime, orderNum, dishName, portion, num); Record[] newRecords = new Record[this.profitRecords.length + 1]; for(int i = 0; i < this.profitRecords.length; i++){ newRecords[i] = this.profitRecords[i]; } newRecords[this.profitRecords.length] = newRecord; this.profitRecords = newRecords; return newRecord; } public Record addAGiveRecord(int orderNum, String dishName, int portion, int num, Table profitTable){ Record newRecord = new Record(this.orderDate, this.orderTime, orderNum, dishName, portion, num); this.givenPrice += newRecord.getPrice()/* * profitTableOrder.getDiscount()*/; profitTable.addAProfitRecord(orderNum, dishName, portion, num); return newRecord; } public Record delARecordByOrderNum(int orderNum){ for(int i = 0; i < this.records.length; i++){ Record record = this.records[i]; if(record.getOredrId() == orderNum){ Record[] newRecords = new Record[this.records.length - 1]; for(int j = 0; j < i; j++){ newRecords[j] = this.records[j]; } for(int j = i; j < this.records.length - 1; j++){ newRecords[j] = this.records[j + 1]; } this.records = newRecords; return record; } } return null; } public Record findRecordByNum(int orderNum){ for(int i = 0; i < this.records.length; i++){ if(this.records[i].getOredrId() == orderNum){ return this.records[i]; } } return null; } } class TimeUtil{ int hour; int minute; int second; public TimeUtil(int hour, int minute, int second){ this.hour = hour; this.minute = minute; this.second = second; } public int getTolalSeconds() { return (this.hour * 60 + this.minute) * 60 + this.second; } public boolean isEarlyThan(TimeUtil a){ if(this.hour < a.hour) return true; if(this.hour > a.hour) return false; if(this.minute < a.minute) return true; if(this.minute > a.minute) return false; if(this.second < a.second) return true; return false; } public boolean isBetween(TimeUtil a, TimeUtil b){ if(a.isEarlyThan(b)){ if(!this.isEarlyThan(a) && !b.isEarlyThan(this)) return true; return false; } else { if(!this.isEarlyThan(a) || !b.isEarlyThan(this)) return true; return false; } } public int compareTo(TimeUtil time) { return Math.abs(this.getTolalSeconds() - time.getTolalSeconds()); } public boolean check() { if(this.hour < 0 || this.hour > 23) return false; if(this.minute < 0 || this.minute > 59) return false; if(this.second < 0 || this.second > 59) return false; return true; } } class DateUtil{ private int year; private int month; private int day; private static int[] mon_maxnum = new int[]{31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public DateUtil(){ } public DateUtil(int year, int month, int day){ this.year = year; this.month = month; this.day = day; } public int getYear(){ return this.year; } public void setYear(int year){ this.year = year; } public int getMonth(){ return this.month; } public void setMonth(int month){ this.month = month; } public int getDay(){ return this.day; } public void setDay(int day){ this.day = day; } public static boolean isLeapYear(int year){ if(year % 400 == 0 || year % 100 != 0 && year % 4 == 0)return true; return false; } public boolean checkInputValidityIgnoreYear(){ if(this.month < 1 || this.month > 12) return false; if(this.day < 1 || this.month != 2 && this.day > mon_maxnum[month]) return false; if(this.month == 2){ if(isLeapYear(this.year) && day > 29) return false; if(!isLeapYear(this.year) && day > 28) return false; } return true; } public DateUtil getNextDate(){ DateUtil nextDate = new DateUtil(this.year, this.month, this.day + 1); if(nextDate.checkInputValidityIgnoreYear()) return nextDate; nextDate.setDay(1); nextDate.setMonth(this.month + 1); if(nextDate.checkInputValidityIgnoreYear()) return nextDate; nextDate.setMonth(1); nextDate.setYear(this.year + 1); return nextDate; } public boolean compareDates(DateUtil date){ if(this.year < date.getYear()) return false; if(this.year > date.getYear()) return true; if(this.month < date.getMonth()) return false; if(this.month > date.getMonth()) return true; if(this.day < date.getDay()) return false; return true; } public boolean equalTwoDates(DateUtil date){ if(this.year == date.getYear() && this.month == date.getMonth() && this.day == date.getDay()) return true; return false; } public int getDaysofDates(DateUtil date){ if(this.equalTwoDates(date)) return 0; if(this.compareDates(date)){ DateUtil nextDate = date; int n = 0; while(!this.equalTwoDates(nextDate)){ nextDate = nextDate.getNextDate(); n++; } return n; } DateUtil nextDate = this; int n = 0; while(!nextDate.equalTwoDates(date)){ nextDate = nextDate.getNextDate(); n++; } return n; } public int getWeek(){ DateUtil anchorDate = new DateUtil(2000, 1, 2); return this.getDaysofDates(anchorDate) % 7; } }
再然后就是实验九的题目了,这个还是比较简单的,只考察了我们统计Java程序中关键词的出现次数的问题
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit
行作为结束标志
输出格式:
- 当未输入源码时,程序输出
Wrong Format
- 当没有统计数据时,输出为空
- 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为
数量\t关键字
这里给出源代码
import java.util.*; import java.util.regex.*; public class Main { public Main() { } public static void main(String[] args) { HashMap<String, Integer> hashMap = new HashMap<>(); Scanner in = new Scanner(System.in); String keyWord = "abstract assert boolean break byte case catch char class const continue default do " + " double else enum extends final finally float for goto if implements import instanceof int " + "interface long native new package private protected public return strictfp short static super " + "switch synchronized this throw throws transient try void volatile while true false null"; String[] finish = keyWord.split(" "); for (String e : finish) hashMap.put(e, 0); String k = null; int count = 0; StringBuilder b = new StringBuilder(); while (!(k = in.nextLine().trim()).equals("exit")) { if (k.matches(".*//.*")) continue; b.append(k + " "); } k = b.toString(); Pattern pattern = Pattern.compile("/\\*(.*)?\\*/"); Matcher matcher = pattern.matcher(k); while (matcher.find()) { k = k.replace(matcher.group(), " "); matcher = pattern.matcher(k); } if (k.length() == 0) { System.out.print("Wrong Format"); System.exit(0); } while (matcher.find()) { k = k.replace(matcher.group(), " "); matcher = pattern.matcher(k); } k = k.replaceAll("\\p{P}", " "); pattern = Pattern.compile("\"(.*?)\""); matcher = pattern.matcher(k); String[] temp = k.split("\\s+"); for (String e : temp) if (hashMap.containsKey(e)) { hashMap.put(e, hashMap.get(e) + 1); count = 1; } if (count == 0) System.exit(0); List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>((Collection<? extends Map.Entry<String, Integer>>) hashMap.entrySet()); list.sort((o1, o2) -> o2.getKey().compareTo(o1.getKey())); for (int i = list.size() - 1; i >= 0; i--) { if (list.get(i).getValue() == 0) continue; System.out.printf("%d\t", list.get(i).getValue()); System.out.println(list.get(i).getKey()); } } }
然后是实验十
这里分析一下实验十的第一题和最后一题
7-1 容器-HashMap-检索
输入多个学生的成绩信息,包括:学号、姓名、成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
使用HashMap存储学生信息,并实现根据学号的检索功能
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩
以“end”为输入结束标志
end之后输入某个学号,执行程序输出该生的详细信息
输出格式:
输出查询到的学生信息格式:学号+英文空格+姓名+英文空格+成绩
如果没有查询到,则输出:"The student "+查询的学号+" does not exist"
import java.util.HashMap; import java.util.Scanner; public class Main{ public static void main( String[] args ) { Scanner sc = new Scanner ( System.in ); HashMap<String, Student> hashMap = new HashMap<> ( ); while (sc.hasNext ( )){ String str = sc.nextLine ( ); if ( str.equals ( "end" ) ) break; extracted ( hashMap, str ); } String id = getString ( sc ); if ( hashMap.containsKey ( id ) ){ System.out.println ( id + " " + hashMap.get ( id ).name + " " + hashMap.get ( id ).score ); } else{ System.out.println ( "The student " + id + " does not exist" ); } } private static String getString( Scanner sc ) { String id = sc.nextLine ( ); return id; } private static void extracted( HashMap<String, Student> hm, String str ) { String[] n = str.split ( " " ); hm.put ( n[0], new Student ( n[1], Integer.parseInt ( n[2] ) ) ); } } class Student{ String name; int score; public Student( String name, int score ) { this.name = name; this.score = score; } }
然后是实验十的最后一题
7-4 动物发声模拟器(多态)
设计一个动物发生模拟器,用于模拟不同动物的叫声。比如狮吼、虎啸、狗旺旺、猫喵喵……。
定义抽象类Animal,包含两个抽象方法:获取动物类别getAnimalClass()、动物叫shout();
然后基于抽象类Animal定义狗类Dog、猫类Cat和山羊Goat,用getAnimalClass()方法返回不同的动物类别(比如猫,狗,山羊),用shout()方法分别输出不同的叫声(比如喵喵、汪汪、咩咩)。
最后编写AnimalShoutTest类测试,输出:
猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩
其中,在AnimalShoutTestMain类中,用speak(Animal animal){}方法输出动物animal的叫声,在main()方法中调用speak()方法,分别输出猫、狗和山羊对象的叫声。
请在下面的【】处添加代码
//动物发生模拟器. 请在下面的【】处添加代码。 public class Main { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); Goat goat = new Goat(); speak(cat); speak(dog); speak(goat); } //定义静态方法speak() public static void speak(Animal animal){ extracted ( animal ); } private static void extracted( Animal animal ) { System.out.println( animal.getAnimalClass()+"的叫声:"+ animal.shout()); } } //定义抽象类Animal abstract class Animal{ abstract String shout(); abstract String getAnimalClass(); } //基于Animal类,定义猫类Cat,并重写两个抽象方法 class Cat extends Animal{ String name="猫"; String shout() { return "喵喵"; } String getAnimalClass() { return name; } } //基于Animal类,定义狗类Dog,并重写两个抽象方法 class Dog extends Animal{ String name="狗"; String shout() { return "汪汪"; } String getAnimalClass() { return name; } } //基于Animal类,定义山羊类Goat,并重写两个抽象方法 class Goat extends Animal{ String name="山羊"; String shout() { return "咩咩"; } String getAnimalClass() { return name; } }
3.踩坑总结
有的时候写的程序代码过于冗长,导致超时或者过不了,以后还是要注意优化的
4.改进建议
相比刚入门的时候进步了很多,但是还有很多命名和格式的地方可以用来改进,不是所有的东西老师都会教。
java是一门语言,需要花大量的时间来进行学习,刻苦与用功是必须的。我们需要具有自主学习能力,遇到问题不会要多去询问,在语言学习的过程中不断丰富自我。
5.教学评价
1.教学理念
本课程以成果导向教育(Outcome based education,简称OBE),为理念,让我们在深度学习之后取得了成果,得到了进步。
2.教学方法
本课程的教学方法是边讲边练,不仅让我们刚学到的知识得到了练习,更让我们在练习中得到了巩固。
3.
标签:11,return,int,PTA,空格,实验,英文,table,public
From: https://www.cnblogs.com/mlz1106/p/17510232.html