第二次作业
一.前言:总结三次题目集的题量、知识点、难度等情况
题目集四:
第四次题目集共4题,总体比较简单,涉及到的知识点都很基础,7-3涉及日期类的使,7-2主要是对字符串的比较和排序;7-1和7-4都是菜单计价程序,7-4比7-1多了桌的概念,主要涉及到创建类和创建对象,正则表达式,对输入的进行操作
题目集五:
第五次题目集共1题,总体比较难,是菜单计价程序-3的迭代,其设计知识点主要和菜单计价程序-3差不多,主要增加了一些功能如对菜单,点菜记录,桌号的错误的输入格式和不符合规定的输入和输出,其中对输入的判定较为复杂,容易出现较多bug,输出要输出每一桌的原价和打折后的价且同一桌号同一时间段要进行合并
题目集六:
第六次题目集共1题,总体较难,菜单计价程序-3的另一种迭代,其设计知识点主要和菜单计价程序-3差不多,主要增加了一些特殊需求如特色菜及其味道,甜度,酸度,辣度和桌号的用户及其电话号码输出时要输出同一个用户所需付的总价并要按名字排序
期中考试:
期中考试较为简单,涉及到的知识点也很基础,主要就是Java中的类的创建和运用,和父类的继承和多态,其中含有较多选择提都是一些关于Java基础知识的,没有任何难点
二.设计与分析:
题目集四 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”
最后输出订单上所有菜品的总价(整数数值),
本次题目不考虑其他错误情况,如:菜单订单顺序颠倒、不符合格式的输入、序号重复等。
输入样例:
在这里给出一组输入。例如:
麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end
输出样例:
在这里给出相应的输出。例如:
1 麻婆豆腐 36
2 油淋生菜 27
63
输入样例1:
订单中包含删除记录。例如:
麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end
输出样例1:
在这里给出相应的输出。例如:
1 麻婆豆腐 36
2 油淋生菜 27
27
输入样例2:
订单中包含不存在的菜品记录。例如:
麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
end
输出样例2:
在这里给出相应的输出。例如:
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
63
输入样例3:
订单中包含删除信息以及不存在的菜品记录。例如:
麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 delete
7 delete
end
输出样例3:
在这里给出相应的输出。例如:
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
27
输入样例4:
订单中包含删除信息以及不存在的菜品记录。例如:
麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
end
输出样例4:
在这里给出相应的输出。例如:
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
delete error;
63
import java.util.List; import java.util.ArrayList; import java.util.Scanner; import java.util.regex.*; class Dish{ String name;//菜品名称 int unit_price; //单价 public int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) { float Price = (float)unit_price*((float)portion+1)/2; return Math.round(Price); } public Dish(String name,int unit_price){ this.name = name; this.unit_price = unit_price; } } class Menu{ ArrayList<Dish> deshes = new ArrayList<>(); public void setMenu(String name,int unit_price){ int flag = 0; Dish de = new Dish(name,unit_price); for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(name)){ this.deshes.set(i,de); flag = 1; } } if(flag!=1){ deshes.add(de); } } public Dish searthDish(String dishName) { for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(dishName)){ return this.deshes.get(i); } } System.out.println(dishName + " does not exist"); return null; } } class Record { int orderNum; int num; Dish d; int portion;//份额(1/2/3代表小/中/大份) public Record(int orderNum,String name,int portion,int num,Menu menu){ this.orderNum = orderNum; this.d = menu.searthDish(name); this.portion = portion; this.num = num; } public int getPrice(){//计价,计算本条记录的价 if(this.d!=null){ return this.d.getPrice(this.portion)*this.num; } else return 0; } } class Order { ArrayList<Record> records = new ArrayList<>(); public int getTotalPrice()//计算订单的总价 { int j=0; for(int i = 0; i < records.size(); i++){ j = j + records.get(i).getPrice(); } return j; } public void addARecord(int orderNum,String dishName,int portion,int num,Menu menu)//添加一条菜品信息到订单中。 { Record r = new Record(orderNum,dishName,portion,num,menu); if(r.d!=null){ System.out.println(r.orderNum +" "+ r.d.name +" "+ r.getPrice()); } records.add(r); } public void delARecordByOrderNum(int orderNum){ int flag = 0; for(int i = 0; i < records.size(); i++){ if(this.records.get(i).orderNum == orderNum){ records.remove(i); flag = 1; } } if(flag == 0){ System.out.println("delete error;"); } } } public class Main{ public static void main(String[] args) { int unit_price,orderNum,portion,num; String s; Menu menu = new Menu(); Order order = new Order(); Scanner input = new Scanner(System.in); while(!"end".equals(s = input.nextLine())){ String[] strings = s.split(" "); if(1 == match(s)){ unit_price = Integer.parseInt(strings[1]); menu.setMenu(strings[0],unit_price); } else if(match(s) == 2){ orderNum = Integer.parseInt(strings[0]); portion = Integer.parseInt(strings[2]); num = Integer.parseInt(strings[3]); order.addARecord(orderNum,strings[1],portion,num,menu); } else if(match(s) == 3){ orderNum = Integer.parseInt(strings[0]); order.delARecordByOrderNum(orderNum); } } System.out.print(order.getTotalPrice()); } static int match(String s){ String regex1 = "^[\u4e00-\u9fa5]{0,}\\s\\d+$"; String regex2 = "^\\d+\\s[\u4e00-\u9fa5]{0,}\\s[123]\\s\\d+$"; String regex3 = "^\\d+\\s(delete)$"; if(s.matches(regex1)){ return 1; } else if(s.matches(regex2)){ return 2; } else if(s.matches(regex3)){ return 3; } else{ return 0; } } }
题目集四 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+英文空格+桌号+“:”+英文空格+当前桌的总价
本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。
输入样例:
在这里给出一组输入。例如:
麻婆豆腐 12 油淋生菜 9 table 1 2023/3/22 12/2/3 1 麻婆豆腐 2 2 2 油淋生菜 1 3 end输出样例:
在这里给出相应的输出。例如:
table 1: 1 麻婆豆腐 36 2 油淋生菜 27 table 1: 38输入样例1:
在这里给出一组输入。例如:
麻婆豆腐 12 油淋生菜 9 table 1 2023/3/22 17/0/0 1 麻婆豆腐 2 2 2 油淋生菜 1 3 1 delete end输出样例1:
在这里给出相应的输出。例如:
table 1: 1 麻婆豆腐 36 2 油淋生菜 27 table 1: 22输入样例2:
在这里给出一组输入。例如:
麻婆豆腐 12 油淋生菜 9 table 1 2023/3/22 16/59/59 1 麻婆豆腐 2 2 2 油淋生菜 1 3 1 delete end输出样例2:
在这里给出相应的输出。例如:
table 1: 1 麻婆豆腐 36 2 油淋生菜 27 table 1 out of opening hours输入样例3:
在这里给出一组输入。例如:
麻婆豆腐 12 油淋生菜 9 table 1 2022/12/5 15/03/02 1 麻婆豆腐 2 2 2 油淋生菜 1 3 3 麻辣鸡丝 1 2 5 delete 7 delete table 2 2022/12/3 15/03/02 1 麻婆豆腐 2 2 2 油淋生菜 1 3 3 麻辣鸡丝 1 2 7 delete end输出样例3:
在这里给出相应的输出。例如:
table 1: 1 麻婆豆腐 36 2 油淋生菜 27 麻辣鸡丝 does not exist delete error; delete error; table 2: 1 麻婆豆腐 36 2 油淋生菜 27 麻辣鸡丝 does not exist delete error; table 1 out of opening hours table 2: 63输入样例4:
在这里给出一组输入。例如:
麻婆豆腐 12 油淋生菜 9 table 1 2022/12/3 19/5/12 1 麻婆豆腐 2 2 2 油淋生菜 1 3 3 麻辣鸡丝 1 2 table 2 2022/12/3 15/03/02 1 麻婆豆腐 2 2 2 油淋生菜 1 3 3 麻辣鸡丝 1 2 1 4 麻婆豆腐 1 1 7 delete end输出样例4:
在这里给出相应的输出。例如:
table 1: 1 麻婆豆腐 36 2 油淋生菜 27 麻辣鸡丝 does not exist table 2: 1 麻婆豆腐 36 2 油淋生菜 27 麻辣鸡丝 does not exist 4 table 2 pay for table 1 12 delete error; table 1: 63 table 2: 75
import java.util.List; import java.util.ArrayList; import java.util.Scanner; import java.util.regex.*; import java.text.SimpleDateFormat; import java.time.*; import java.util.Date; import java.time.Period; import java.time.temporal.ChronoUnit; class Dish{ String name;//菜品名称 int unit_price; //单价 public int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) { float Price = (float)unit_price*((float)portion+1)/2; return Math.round(Price); } public Dish(String name,int unit_price){ this.name = name; this.unit_price = unit_price; } } class Menu{ ArrayList<Dish> deshes = new ArrayList<>(); public void setMenu(String name,int unit_price){ int flag = 0; Dish de = new Dish(name,unit_price); for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(name)){ this.deshes.set(i,de); flag = 1; } } if(flag!=1){ deshes.add(de); } } public Dish searthDish(String dishName) { for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(dishName)){ return this.deshes.get(i); } } System.out.println(dishName + " does not exist"); return null; } } class Record { int orderNum; int num; Dish d; int portion;//份额(1/2/3代表小/中/大份) public Record(int orderNum,String name,int portion,int num,Menu menu){ this.orderNum = orderNum; this.d = menu.searthDish(name); this.portion = portion; this.num = num; } public int getPrice(){//计价,计算本条记录的价 if(this.d!=null){ return this.d.getPrice(this.portion)*this.num; } else return 0; } } class Order { ArrayList<Record> records = new ArrayList<>(); public int getTotalPrice()//计算订单的总价 { int j=0; for(int i = 0; i < records.size(); i++){ j = j + records.get(i).getPrice(); } return j; } public void addARecord1(int orderNum,String dishName,int portion,int num,Menu menu)//添加一条菜品信息到订单中。 { Record r = new Record(orderNum,dishName,portion,num,menu); if(r.d!=null){ System.out.println(r.orderNum +" "+ r.d.name +" "+ r.getPrice()); } records.add(r); } public void addARecord2(int n1,int n2,int orderNum,String dishName,int portion,int num,Menu menu)//添加一条菜品信息到订单中。 { Record r = new Record(orderNum,dishName,portion,num,menu); if(r.d!=null){ System.out.println(r.orderNum +" table "+ n1 +" pay for table "+ n2 +" "+ r.getPrice()); } records.add(r); } public void delARecordByOrderNum(int orderNum){ int flag = 0; for(int i = 0; i < records.size(); i++){ if(this.records.get(i).orderNum == orderNum){ records.remove(i); flag = 1; } } if(flag == 0){ System.out.println("delete error;"); } } } class Table{ int num; String date; String time; Order order = new Order(); public void setTable(int num,String date,String time){ this.num = num; this.date = date; this.time = time; } public void out(){ String[] strings1 = this.date.split("/"); String[] strings2 = this.time.split("/"); int year = Integer.parseInt(strings1[0]); int moon = Integer.parseInt(strings1[1]); int day = Integer.parseInt(strings1[2]); int n1 = Integer.parseInt(strings2[0]); int n2 = Integer.parseInt(strings2[1]); int n3 = Integer.parseInt(strings2[2]);;; LocalDate localDate = LocalDate.of(year, moon, day); int n = localDate.getDayOfWeek().getValue(); int d = n1*3600+n2*60+n3; if(1<=n&&n<=5&&61200<=d&&d<=73800){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()*0.8)); } else if(1<=n&&n<=5&&37800<=d&&d<=52200){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()*0.6)); } else if(6<=n&&n<=7&&34200<=d&&d<=77400){ System.out.print("table "+ this.num +": " + this.order.getTotalPrice()); } else{ System.out.print("table "+ this.num +" out of opening hours"); } } } public class Main{ public static void main(String[] args) { int unit_price,orderNum,portion,num,n; String s; Menu menu = new Menu(); Table t = new Table(); Scanner input = new Scanner(System.in); ArrayList<Table> tables = new ArrayList<>(); while(!"end".equals(s = input.nextLine())){ String[] strings = s.split(" "); if(1 == match(s)){ unit_price = Integer.parseInt(strings[1]); menu.setMenu(strings[0],unit_price); } else if(match(s) == 2){ orderNum = Integer.parseInt(strings[0]); portion = Integer.parseInt(strings[2]); num = Integer.parseInt(strings[3]); t.order.addARecord1(orderNum,strings[1],portion,num,menu); } else if(match(s) == 3){ orderNum = Integer.parseInt(strings[0]); t.order.delARecordByOrderNum(orderNum); } else if(match(s) == 4){ tables.add(t); t = new Table(); num = Integer.parseInt(strings[1]); t.setTable(num,strings[2],strings[3]); System.out.println("table"+ " "+num+": "); } else if(match(s) == 5){ orderNum = Integer.parseInt(strings[1]); portion = Integer.parseInt(strings[3]); num = Integer.parseInt(strings[4]); n = Integer.parseInt(strings[0]); t.order.addARecord2(t.num,n,orderNum,strings[2],portion,num,menu); } } tables.add(t); for(int i = 1; i < tables.size(); i++){ if(i!=tables.size()-1){ tables.get(i).out(); System.out.println(); } else { tables.get(i).out(); } } } static int match(String s){ String regex1 = "^[\u4e00-\u9fa5]{0,}\\s\\d+$"; String regex2 = "^\\d+\\s[\u4e00-\u9fa5]{0,}\\s[123]\\s\\d+$"; String regex3 = "^\\d+\\s(delete)$"; String regex4 = "^(table)\\s\\d+\\s\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}/\\d{1,2}/\\d{1,2}$"; String regex5 = "^\\d+\\s\\d+\\s[\u4e00-\u9fa5]{0,}\\s[123]\\s\\d+$"; if(s.matches(regex1)){ return 1; } else if(s.matches(regex2)){ return 2; } else if(s.matches(regex3)){ return 3; } else if(s.matches(regex4)){ return 4; } else if(s.matches(regex5)){ return 5; } else{ return 0; } } }
题目集五 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+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价
输入样例:
在这里给出一组输入。例如:
麻婆豆腐 12 油淋生菜 9 T table 31 2023/2/1 14/20/00 1 麻婆豆腐 1 16 2 油淋生菜 1 2 2 delete 2 delete end输出样例:
在这里给出相应的输出。例如:
table 31: 1 num out of range 16 2 油淋生菜 18 deduplication 2 table 31: 0 0输入样例1:
份数超出范围+份额超出范围。例如:
麻婆豆腐 12 油淋生菜 9 T table 31 2023/2/1 14/20/00 1 麻婆豆腐 1 16 2 油淋生菜 4 2 end输出样例1:
份数超出范围+份额超出范围。例如:
table 31: 1 num out of range 16 2 portion out of range 4 table 31: 0 0输入样例2:
桌号信息错误。例如:
麻婆豆腐 12 油淋生菜 9 T table a 2023/3/15 12/00/00 1 麻婆豆腐 1 1 2 油淋生菜 2 1 end输出样例2:
在这里给出相应的输出。例如:
wrong format输入样例3:
混合错误:桌号信息格式错误+混合的菜谱信息(菜谱信息忽略)。例如:
麻婆豆腐 12 油淋生菜 9 T table 55 2023/3/31 12/000/00 麻辣香锅 15 1 麻婆豆腐 1 1 2 油淋生菜 2 1 end输出样例3:
在这里给出相应的输出。例如:
wrong format输入样例4:
错误的菜谱记录。例如:
麻婆豆腐 12.0 油淋生菜 9 T table 55 2023/3/31 12/00/00 麻辣香锅 15 1 麻婆豆腐 1 1 2 油淋生菜 2 1 end输出样例4:
在这里给出相应的输出。例如:
wrong format table 55: invalid dish 麻婆豆腐 does not exist 2 油淋生菜 14 table 55: 14 10输入样例5:
桌号格式错误(以“table”开头)+订单格式错误(忽略)。例如:
麻婆豆腐 12 油淋生菜 9 T table a 2023/3/15 12/00/00 1 麻婆 豆腐 1 1 2 油淋生菜 2 1 end输出样例5:
在这里给出相应的输出。例如:
wrong format输入样例6:
桌号格式错误,不以“table”开头。例如:
麻婆豆腐 12 油淋生菜 9 T table 1 2023/3/15 12/00/00 1 麻婆豆腐 1 1 2 油淋生菜 2 1 tab le 2 2023/3/15 12/00/00 1 麻婆豆腐 1 1 2 油淋生菜 2 1 end输出样例6:
在这里给出相应的输出。例如:
table 1: 1 麻婆豆腐 12 2 油淋生菜 14 wrong format record serial number sequence error record serial number sequence error table 1: 26 17
import java.util.List; import java.util.ArrayList; import java.util.Scanner; import java.util.regex.*; import java.text.SimpleDateFormat; import java.time.*; import java.util.Date; import java.time.Period; import java.time.temporal.ChronoUnit; class Dish{ String name;//菜品名称 int unit_price; //单价 boolean T = false; public int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) { float Price = (float)unit_price*((float)portion+1)/2; return Math.round(Price); } public Dish(String name,int unit_price){ this.name = name; this.unit_price = unit_price; } public Dish(String name,int unit_price,String s){ this.name = name; this.unit_price = unit_price; this.T = !this.T; } } class Menu{ ArrayList<Dish> deshes = new ArrayList<>(); public void setMenu1(String name,int unit_price){ int flag = 0; if(unit_price<=0||300<=unit_price){ System.out.println(name + " price out of range " + unit_price); } else{ Dish de = new Dish(name,unit_price); for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(name)){ this.deshes.set(i,de); flag = 1; } } if(flag!=1){ deshes.add(de); } } } public void setMenu2(String name,int unit_price,String l){ int flag = 0; if(unit_price<=0||300<=unit_price){ System.out.println(name + " price out of range " + unit_price); } else{ Dish de = new Dish(name,unit_price,l); for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(name)){ this.deshes.set(i,de); flag = 1; } } if(flag!=1){ deshes.add(de); } } } public Dish searthDish(String dishName) { for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(dishName)){ return this.deshes.get(i); } } System.out.println(dishName + " does not exist"); return null; } } class Record { int orderNum; int num; Dish d; int portion;//份额(1/2/3代表小/中/大份) public Record(){ } public Record(Dish d,int portion,int num){ this.d = d; this.portion = portion; this.num = num; } public Record(int orderNum,String name,int portion,int num,Menu menu){ this.orderNum = orderNum; this.d = menu.searthDish(name); this.portion = portion; this.num = num; } public int getPrice(){//计价,计算本条记录的价 if(this.d!=null){ //System.out.println(Math.round((float)(this.d.getPrice(this.portion)*this.num))); return Math.round((float)(this.d.getPrice(this.portion)*this.num)); } else return 0; } } class Order { int max=0; ArrayList<Record> records = new ArrayList<>(); ArrayList<Record> newrecords = new ArrayList<>(); ArrayList<Integer> delete = new ArrayList<Integer>(); public void setnewrecords(ArrayList<Record> newrecordsrecords){ this.newrecords = new ArrayList<>(newrecordsrecords); } public float getTotalPrice()//计算订单的总价 { float j=0; for(int i = 0; i < newrecords.size(); i++){ j = j + newrecords.get(i).getPrice(); } return j; } public int getTotalPrice1(LocalDateTime localDateTime)//计算订单的总价 { int j=0; int hour = localDateTime.getHour(); int minute = localDateTime.getMinute(); int second = localDateTime.getSecond(); int n = localDateTime.getDayOfWeek().getValue(); int d = hour*3600+minute*60+second; for(int i = 0; i < newrecords.size(); i++){ if(1<=n&&n<=5&&61200<=d&&d<=73800){ if(newrecords.get(i).d.T){ j = j +Math.round((float)(newrecords.get(i).getPrice()*(float)0.7)); } else{ j = j + Math.round((float)(newrecords.get(i).getPrice()*(float)0.8)); } } else if(1<=n&&n<=5&&37800<=d&&d<=52200){ if(newrecords.get(i).d.T){ j = j + Math.round((float)(newrecords.get(i).getPrice()*(float)0.7)); } else{ j = j + Math.round((float)(newrecords.get(i).getPrice()*(float)0.6)); } } else { j = j + newrecords.get(i).getPrice(); } } return j; } public void addARecord1(int orderNum,String dishName,int portion,int num,Menu menu)//添加一条菜品信息到订单中。 { Record r = new Record(orderNum,dishName,portion,num,menu); if(orderNum>max){ if(r.d!=null){ if(portion<1||portion>3){ System.out.println(r.orderNum +" portion out of range "+ r.portion); } else if(num>15){ System.out.println(r.orderNum +" num out of range "+ r.num); } else{ this.max = orderNum; System.out.println(r.orderNum +" "+ r.d.name +" "+ Math.round(r.getPrice())); records.add(r); } } } else { System.out.println("record serial number sequence error"); } } public void addARecord2(int n1,int n2,int orderNum,String dishName,int portion,int num,Menu menu)//添加一条菜品信息到订单中。 { Record r = new Record(orderNum,dishName,portion,num,menu); if(r.d!=null){ if(portion<1||portion>3){ System.out.println(r.orderNum +" portion out of range "+ r.portion); } else if(num>15){ System.out.println(r.orderNum +" num out of range "+ r.num); } else{ System.out.println(r.orderNum +" table "+ n1 +" pay for table "+ n2 +" "+ r.getPrice()); records.add(r); } } } public void delARecordByOrderNum(int orderNum){ int flag = 0; for(int j = 0; j < delete.size(); j++){ if(delete.get(j)==orderNum){ System.out.println("deduplication " + orderNum); flag = 1; } } for(int i = 0; i < records.size(); i++){ if(this.records.get(i).orderNum == orderNum){ delete.add(orderNum); records.remove(i); flag = 1; } } if(flag == 0){ System.out.println("delete error;"); } } public ArrayList<Record> getRecords(){ return records; } } class Table{ int num; LocalDateTime localDateTime; Order order = new Order(); public Table(){ } public Table(int num,LocalDateTime localDateTime,Order order){ this.num = num; this.localDateTime = localDateTime; this.order = order; } public Table(int num,LocalDateTime localDateTime){ this.num = num; this.localDateTime = localDateTime; } public void out(){ int hour = this.localDateTime.getHour(); int minute = this.localDateTime.getMinute(); int second = this.localDateTime.getSecond(); int n = this.localDateTime.getDayOfWeek().getValue(); int d = hour*3600+minute*60+second; if(1<=n&&n<=5&&61200<=d&&d<=73800){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()) + " " + this.order.getTotalPrice1(this.localDateTime)); } else if(1<=n&&n<=5&&37800<=d&&d<=52200){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()) + " " + this.order.getTotalPrice1(this.localDateTime)); } else if(6<=n&&n<=7&&34200<=d&&d<=77400){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()) + " " + Math.round(this.order.getTotalPrice())); } } public boolean JudgeDateTime(LocalDateTime localDateTime1){ int n = this.localDateTime.getDayOfWeek().getValue(); int d1 = this.localDateTime.getHour()*3600+this.localDateTime.getMinute()*60+this.localDateTime.getSecond(); int d2 = localDateTime1.getHour()*3600+localDateTime1.getMinute()*60+localDateTime1.getSecond(); if(Duration.between(this.localDateTime, localDateTime1).toDays()==0&&1<=n&&n<=5){ if((61200<=d1&&d1<=73800&&61200<=d2&&d2<=73800)||(37800<=d1&&d1<=52200&&37800<=d2&&d2<=52200)){ return true; } else{ return false; } } else if(Duration.between(this.localDateTime, localDateTime1).toDays()==0&&6<=n&&n<=7){ if(d1-d2>3600||d1-d2<-3600){ return false; } else{ return true; } } else{ return false; } } } public class Main{ public static void main(String[] args) { int unit_price,orderNum,portion,num,n,flag1=0; String s; Menu menu = new Menu(); Table t = new Table(); Scanner input = new Scanner(System.in); ArrayList<Table> tables = new ArrayList<>(); ArrayList<Table> newtables = new ArrayList<>(); s = input.nextLine(); while(!"end".equals(s)){ String[] strings = s.split(" "); if(1 == match(s)){ unit_price = Integer.parseInt(strings[1]); menu.setMenu1(strings[0],unit_price); } else if(s.matches("^[\u4e00-\u9fa5]{0,}\\s[1-9][0-9]*\\s(T)$")){ unit_price = Integer.parseInt(strings[1]); menu.setMenu2(strings[0],unit_price,strings[2]); } else if(s.matches("^(table)(.*?)$")){ break; } else{ System.out.println("wrong format"); } s = input.nextLine(); } out: while(!"end".equals(s)){ String[] strings = s.split(" "); if(1 == match(s)||s.matches("^[\u4e00-\u9fa5]{0,}\\s[1-9][0-9]*\\s(T)$")){ System.out.println("invalid dish"); } else if(match(s) == 2){ orderNum = Integer.parseInt(strings[0]); portion = Integer.parseInt(strings[2]); num = Integer.parseInt(strings[3]); t.order.addARecord1(orderNum,strings[1],portion,num,menu); } else if(match(s) == 3){ orderNum = Integer.parseInt(strings[0]); t.order.delARecordByOrderNum(orderNum); } else if(s.matches("^(table)(.*?)$")){ tables.add(t); t = new Table(); t = JudgeTable(s); if(t == null){ while(!"end".equals(s)){ s = input.nextLine(); if(s.matches("^(table)(.*?)$")){ t = JudgeTable(s); if(t != null){ break; } } else if("end".equals(s)){ break out; } } } } else if(match(s) == 5){ orderNum = Integer.parseInt(strings[1]); portion = Integer.parseInt(strings[3]); num = Integer.parseInt(strings[4]); n = Integer.parseInt(strings[0]); for(int i = 1; i < tables.size(); i++){ if(n==tables.get(i).num){ t.order.addARecord2(t.num,n,orderNum,strings[2],portion,num,menu); break; } if(i==(tables.size()-1)){ System.out.println("Table number :" + n + " does not exist"); } } } else{ System.out.println("wrong format"); } s = input.nextLine(); } if(t!=null){ tables.add(t); } newtables = resettables(tables); for(int i = 1; i < tables.size(); i++){ if(i!=tables.size()-1){ newtables.get(i).order.setnewrecords(resetrecords(tables.get(i).order.getRecords())); newtables.get(i).out(); System.out.println(); } else { newtables.get(i).order.setnewrecords(resetrecords(tables.get(i).order.getRecords())); newtables.get(i).out(); } } } static int match(String s){ String regex1 = "^[\u4e00-\u9fa5]{0,}\\s[1-9][0-9]*$"; String regex2 = "^[1-9][0-9]*\\s[\u4e00-\u9fa5]{0,}\\s\\d{1}\\s[1-9][0-9]*$"; String regex3 = "^\\d+\\s(delete)$"; String regex4 = "^(table)\\s[1-9][0-9]*\\s\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}/\\d{1,2}/\\d{1,2}$"; String regex5 = "^[1-9][0-9]*\\s[1-9][0-9]*\\s[\u4e00-\u9fa5]{0,}\\s\\d{1}\\s[1-9][0-9]*$"; if(s.matches(regex1)){ return 1; } else if(s.matches(regex2)){ return 2; } else if(s.matches(regex3)){ return 3; } else if(s.matches(regex4)){ return 4; } else if(s.matches(regex5)){ return 5; } else{ return 0; } } static Table JudgeTable(String s){ if(!s.matches("^(table)\\s[1-9][0-9]*\\s\\d{4}/\\[1-9][0-9]?/\\[1-9][0-9]?\\s\\[1-9][0-9]?/\\[1-9][0-9]?/\\[1-9][0-9]?$")){ System.out.println("wrong format"); return null; } else{ String[] strings = s.split("[ /]"); int num = Integer.parseInt(strings[1]); int year = Integer.parseInt(strings[2]); int moon = Integer.parseInt(strings[3]); int day = Integer.parseInt(strings[4]); int hour = Integer.parseInt(strings[5]); int minute = Integer.parseInt(strings[6]); int second = Integer.parseInt(strings[7]); int d = hour*3600+minute*60+second; if(num<1||55<num){ System.out.println(num + " table num out of range"); return null; } try{ LocalDateTime localDateTime1 = LocalDateTime.of(year,moon,day,hour,minute,second); int n = localDateTime1.getDayOfWeek().getValue(); if(localDateTime1.isBefore(LocalDateTime.of(2022,1,1,0,0,0))||localDateTime1.isAfter(LocalDateTime.of(2023,12,31,0,0,0))){ System.out.println("not a valid time period"); return null; } else if((1<=n&&n<=5&&61200<=d&&d<=73800)||(1<=n&&n<=5&&37800<=d&&d<=52200)||(6<=n&&n<=7&&34200<=d&&d<=77400)){ System.out.println("table " + num + ": "); Table t1 = new Table(num,localDateTime1); return t1; } else{ System.out.println("table "+ num +" out of opening hours"); return null; } }catch(DateTimeException e){ System.out.println(num + " date error"); return null; } } } static ArrayList<Record> resetrecords(ArrayList<Record> records){ ArrayList<Record> recordss = new ArrayList<>(); ArrayList<Record> newrecords = new ArrayList<>(); for(int i = 0; i < records.size(); i++){ recordss.add(records.get(i)); } for(int i = 0; i < recordss.size(); i++){ Record re = new Record(recordss.get(i).d,recordss.get(i).portion,recordss.get(i).num); for(int j = i+1; j < recordss.size(); j++){ if(recordss.get(i).portion==recordss.get(j).portion&&recordss.get(i).d.name==recordss.get(j).d.name){ re.num = re.num + recordss.get(j).num; recordss.remove(j); j--; } } newrecords.add(re); } recordss.removeAll(recordss); return newrecords; } static ArrayList<Table> resettables(ArrayList<Table> tables){ ArrayList<Table> tabless = new ArrayList<>(); ArrayList<Table> newtables = new ArrayList<>(); for(int i = 0; i < tables.size(); i++){ tabless.add(tables.get(i)); } for(int i = 0; i < tabless.size(); i++){ Table ta = new Table(tabless.get(i).num,tabless.get(i).localDateTime,tabless.get(i).order); for(int j = i+1; j < tabless.size(); j++){ if((tabless.get(i).num==tabless.get(j).num)&&(tabless.get(i).JudgeDateTime(tabless.get(j).localDateTime))){ ta.order.records.addAll(tabless.get(j).order.records); tabless.remove(j); j--; } } newtables.add(ta); } tabless.removeAll(tabless); return newtables; } }
题目集六 7-1 菜单计价程序-5
本题在菜单计价程序-3的基础上增加了部分内容,增加的内容用加粗字体标识。
注意不是菜单计价程序-4,本题和菜单计价程序-4同属菜单计价程序-3的两个不同迭代分支。
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。
菜单由一条或多条菜品记录组成,每条记录一行
每条菜品记录包含:菜名、基础价格 三个信息。
订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。
桌号标识独占一行,包含两个信息:桌号、时间。
桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。
点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。
不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。
删除记录格式:序号 delete
标识删除对应序号的那条点菜记录。
如果序号不对,输出"delete error"
代点菜信息包含:桌号 序号 菜品名称 口味度 份额 份数
代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。
程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。
每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。
折扣的计算方法(注:以下时间段均按闭区间计算):
周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。
周末全价,营业时间:9:30-21:30
如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"
参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }
菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
Dish addDish(String dishName,int unit_price)//添加一道菜品信息
}
点菜记录类:保存订单上的一道菜品记录
Record {
int orderNum;//序号\\
Dish d;//菜品\\
int portion;//份额(1/2/3代表小/中/大份)\\
int getPrice()//计价,计算本条记录的价格\\
}
订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。
delARecordByOrderNum(int orderNum)//根据序号删除一条记录
findRecordByNum(int orderNum)//根据序号查找一条记录
}
### 输入格式:
桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)
菜品记录格式:
菜名+英文空格+基础价格
如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。
点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
删除记录格式:序号 +英文空格+delete
代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数
最后一条记录以“end”结束。
### 输出格式:
按输入顺序输出每一桌的订单记录处理信息,包括:
1、桌号,格式:table+英文空格+桌号+”:”
2、按顺序输出当前这一桌每条订单记录的处理信息,
每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名
如果删除记录的序号不存在,则输出“delete error”
最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价
以上为菜单计价系列-3的题目要求,加粗的部分是有调整的内容。本次课题相比菜单计价系列-3新增要求如下:
1、菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+口味类型+英文空格+基础价格+"T"
例如:麻婆豆腐 川菜 9 T
菜价的计算方法:
周一至周五 7折, 周末全价。
特色菜的口味类型:川菜、晋菜、浙菜
川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣;
晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸;
浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜;
例如:麻婆豆腐 川菜 9 T
输入订单记录时如果是特色菜,添加口味度(辣/酸/甜度)值,格式为:序号+英文空格+菜名+英文空格+口味度值+英文空格+份额+英文空格+份数
例如:1 麻婆豆腐 4 1 9
单条信息在处理时,如果口味度超过正常范围,输出"spicy/acidity/sweetness num out of range : "+口味度值,spicy/acidity/sweetness(辣度/酸度/甜度)根据菜品类型择一输出,例如:
acidity num out of range : 5
输出一桌的信息时,按辣、酸、甜度的顺序依次输出本桌菜各种口味的口味度水平,如果没有某个类型的菜,对应的口味(辣/酸/甜)度不输出,只输出已点的菜的口味度。口味度水平由口味度平均值确定,口味度平均值只综合对应口味菜系的菜计算,不做所有菜的平均。比如,某桌菜点了3份川菜,辣度分别是1、3、5;还有4份晋菜,酸度分别是,1、1、2、2,辣度平均值为3、酸度平均值四舍五入为2,甜度没有,不输出。
一桌信息的输出格式:table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格+"川菜"+数量+辣度+英文空格+"晋菜"+数量+酸度+英文空格+"浙菜"+数量+甜度。
如果整桌菜没有特色菜,则只输出table的基本信息,格式如下,注意最后加一个英文空格:
table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格
例如:table 1: 60 36 川菜 2 爆辣 浙菜 1 微甜
计算口味度时要累计本桌各类菜系所有记录的口味度总和(每条记录的口味度乘以菜的份数),再除以对应菜系菜的总份数,最后四舍五入。
注:本题要考虑代点菜的情况,当前桌点的菜要加上被其他桌代点的菜综合计算口味度平均值。
2、考虑客户订多桌菜的情况,输入时桌号时,增加用户的信息:
格式:table+英文空格+桌号+英文空格+":"+英文空格+客户姓名+英文空格+手机号+日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)
例如:table 1 : tom 13670008181 2023/5/1 21/30/00
约束条件:客户姓名不超过10个字符,手机号11位,前三位必须是180、181、189、133、135、136其中之一。
输出结果时,先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。不考虑各桌时间段的问题,同一个客户的所有table金额都要累加。
输出用户支付金额格式:
用户姓名+英文空格+手机号+英文空格+支付金额
注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:
计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。
将所有记录的菜价累加得到整桌菜的价格。
输入格式:
桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)
菜品记录格式:
菜名+口味类型+英文空格+基础价格
如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。
点菜记录格式:序号+英文空格+菜名+英文空格+辣/酸/甜度值+英文空格+份额+英文空格+份数 注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。辣/酸/甜度取值范围见题目中说明。
删除记录格式:序号 +英文空格+delete
代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称**+英文空格+辣/酸/甜度值+**英文空格+份额+英文空格+分数
最后一条记录以“end”结束。
输出格式:
按输入顺序输出每一桌的订单记录处理信息,包括:
1、桌号,格式:table+英文空格+桌号+“:”+英文空格
2、按顺序输出当前这一桌每条订单记录的处理信息,
每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名
如果删除记录的序号不存在,则输出“delete error”
之后按输入顺序一次输出每一桌所有菜品的价格(整数数值),
格式:table+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格
最后按拼音顺序输出每位客户(不考虑客户同名或拼音相同的情况)的支付金额,格式: 用户姓名+英文空格+手机号+英文空格+支付总金额,按输入顺序排列。
输入样例1:
桌号时间超出营业范围。例如:
麻婆豆腐 川菜 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.List; import java.util.Comparator; import java.util.ArrayList; import java.util.Scanner; import java.util.regex.*; import java.text.SimpleDateFormat; import java.time.*; import java.util.Date; import java.time.Period; import java.time.temporal.ChronoUnit; class Dish{ String name;//菜品名称 int unit_price; //单价 String cuisine = "null"; boolean T = false; public int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) { float Price = (float)unit_price*((float)portion+1)/2; return Math.round(Price); } public Dish(){ } public Dish(String name,int unit_price){ this.name = name; this.unit_price = unit_price; } public Dish(String name,int unit_price,String cuisine,String s){ this.name = name; this.unit_price = unit_price; this.cuisine = cuisine; this.T = !this.T; } } class Menu{ ArrayList<Dish> deshes = new ArrayList<>(); public void setMenu1(String name,int unit_price){ int flag = 0; if(unit_price<=0||300<=unit_price){ System.out.println(name + " price out of range " + unit_price); } else{ Dish de = new Dish(name,unit_price); for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(name)){ this.deshes.set(i,de); flag = 1; } } if(flag!=1){ deshes.add(de); } } } public void setMenu2(String name,int unit_price,String cuisine,String l){ int flag = 0; if(unit_price<=0||300<=unit_price){ System.out.println(name + " price out of range " + unit_price); } else{ Dish de = new Dish(name,unit_price,cuisine,l); for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(name)){ this.deshes.set(i,de); flag = 1; } } if(flag!=1){ deshes.add(de); } } } public Dish searthDish(String dishName) { for (int i = 0; i < this.deshes.size(); i++) { if(this.deshes.get(i).name.equals(dishName)){ return this.deshes.get(i); } } System.out.println(dishName + " does not exist"); return null; } } class Record { int orderNum; int num; int level; Dish d; int portion;//份额(1/2/3代表小/中/大份) boolean isdai = false; boolean ontable = false; public Record(){ } public Record(Dish d,int portion,int num){ this.d = d; this.portion = portion; this.num = num; } public Record(int orderNum,Dish dish,int level,int portion,int num){ this.orderNum = orderNum; this.d = dish; this.level = level; this.portion = portion; this.num = num; } public int getPrice(){//计价,计算本条记录的价 if(this.d!=null){ //System.out.println(Math.round((float)(this.d.getPrice(this.portion)*this.num))); return Math.round((float)(this.d.getPrice(this.portion)*this.num)); } else return 0; } } class Order { int max=0; ArrayList<Record> records = new ArrayList<>(); ArrayList<Record> newrecords = new ArrayList<>(); ArrayList<Integer> delete = new ArrayList<Integer>(); public void setnewrecords(ArrayList<Record> newrecordsrecords){ this.newrecords = new ArrayList<>(newrecordsrecords); } public float getTotalPrice()//计算订单的总价 { float j=0; for(int i = 0; i < newrecords.size(); i++){ j = j + newrecords.get(i).getPrice(); } return j; } public int getTotalPrice1(LocalDateTime localDateTime)//计算订单的总价 { int j=0; int hour = localDateTime.getHour(); int minute = localDateTime.getMinute(); int second = localDateTime.getSecond(); int n = localDateTime.getDayOfWeek().getValue(); int d = hour*3600+minute*60+second; for(int i = 0; i < newrecords.size(); i++){ if(1<=n&&n<=5&&61200<=d&&d<=73800){ if(newrecords.get(i).d.T){ j = j +Math.round((float)(newrecords.get(i).getPrice()*(float)0.7)); } else{ j = j + Math.round((float)(newrecords.get(i).getPrice()*(float)0.8)); } } else if(1<=n&&n<=5&&37800<=d&&d<=52200){ if(newrecords.get(i).d.T){ j = j + Math.round((float)(newrecords.get(i).getPrice()*(float)0.7)); } else{ j = j + Math.round((float)(newrecords.get(i).getPrice()*(float)0.6)); } } else { j = j + newrecords.get(i).getPrice(); } } return j; } public void addARecord1(Record record)//添加一条菜品信息到订单中。 { Record r = new Record(record.orderNum,record.d,record.level,record.portion,record.num); r.ontable = !r.ontable; this.records.add(r); } public void addARecord2(Record record)//添加一条菜品信息到订单中。 { Record r = new Record(record.orderNum,record.d,record.level,record.portion,record.num); r.isdai = !r.isdai; r.ontable = !r.ontable; this.records.add(r); } public void addARecord3(Record record)//添加一条菜品信息到订单中。 { Record r = new Record(record.orderNum,record.d,record.level,record.portion,record.num); this.records.add(r); } public void delARecordByOrderNum(int orderNum){ int flag = 0; for(int i = 0; i < records.size(); i++){ if(this.records.get(i).orderNum == orderNum){ delete.add(orderNum); records.remove(i); flag = 1; } } if(flag == 0){ System.out.println("delete error;"); } } public int getavelevel(String cuisine){ int avelevel = 0; int n = 0; for(int i=0;i<this.records.size();i++){ if(records.get(i).d.cuisine.equals(cuisine)&&records.get(i).ontable){ avelevel = avelevel + records.get(i).level*records.get(i).num; n = n + records.get(i).num; } } if(n==0){ return -1; } float f = (float)(avelevel)/(float)(n); return Math.round(f); } public int getsunnum(String cuisine){ int avelevel = 0; int n = 0; for(int i=0;i<records.size();i++){ if(records.get(i).d.cuisine.equals(cuisine)&&records.get(i).ontable){ avelevel = avelevel + records.get(i).level*records.get(i).num; n = n + records.get(i).num; } } if(n==0){ return -1; } float f = avelevel/n; return n; } public ArrayList<Record> getRecords(){ return records; } } class Table{ int num; String name; String tel; int sum=0; LocalDateTime localDateTime; Order order = new Order(); public Table(){ } public Table(int num,String name,String tel,LocalDateTime localDateTime,Order order){ this.num = num; this.name = name; this.tel = tel; this.localDateTime = localDateTime; this.order = order; } public Table(int num,String name,String tel,LocalDateTime localDateTime){ this.num = num; this.name = name; this.tel = tel; this.localDateTime = localDateTime; } public void out(){ int hour = this.localDateTime.getHour(); int minute = this.localDateTime.getMinute(); int second = this.localDateTime.getSecond(); int n = this.localDateTime.getDayOfWeek().getValue(); int d = hour*3600+minute*60+second; if(1<=n&&n<=5&&61200<=d&&d<=73800){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()) + " " + this.order.getTotalPrice1(this.localDateTime)); } else if(1<=n&&n<=5&&37800<=d&&d<=52200){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()) + " " + this.order.getTotalPrice1(this.localDateTime)); } else if(6<=n&&n<=7&&34200<=d&&d<=77400){ System.out.print("table "+ this.num +": " + Math.round(this.order.getTotalPrice()) + " " + Math.round(this.order.getTotalPrice())); } } public boolean JudgeDateTime(LocalDateTime localDateTime1){ int n = this.localDateTime.getDayOfWeek().getValue(); int d1 = this.localDateTime.getHour()*3600+this.localDateTime.getMinute()*60+this.localDateTime.getSecond(); int d2 = localDateTime1.getHour()*3600+localDateTime1.getMinute()*60+localDateTime1.getSecond(); if(Duration.between(this.localDateTime, localDateTime1).toDays()==0&&1<=n&&n<=5){ if((61200<=d1&&d1<=73800&&61200<=d2&&d2<=73800)||(37800<=d1&&d1<=52200&&37800<=d2&&d2<=52200)){ return true; } else{ return false; } } else if(Duration.between(this.localDateTime, localDateTime1).toDays()==0&&6<=n&&n<=7){ if(d1-d2>3600||d1-d2<-3600){ return false; } else{ return true; } } else{ return false; } } } public class Main{ public static void main(String[] args) { int unit_price,orderNum,portion,num,n,flag1=0; String s; Menu menu = new Menu(); Table t = new Table(); Record record = new Record(); Scanner input = new Scanner(System.in); t = null; ArrayList<Table> tables = new ArrayList<>(); ArrayList<Table> newtables = new ArrayList<>(); s = input.nextLine(); while(!"end".equals(s)){ String[] strings = s.split(" "); if(1 == match(s)){ unit_price = Integer.parseInt(strings[1]); menu.setMenu1(strings[0],unit_price); } else if(s.matches("^[\u4e00-\u9fa5]{0,}\\s[\u4e00-\u9fa5]{0,}\\s[1-9][0-9]*\\s(T)$")){ unit_price = Integer.parseInt(strings[2]); menu.setMenu2(strings[0],unit_price,strings[1],strings[3]); } else if(s.matches("^(table)(.*?)$")){ break; } else{ System.out.println("wrong format"); } s = input.nextLine(); } out: while(!"end".equals(s)){ String[] strings = s.split(" "); if(1 == match(s)||s.matches("^[\u4e00-\u9fa5]{0,}\\s[1-9][0-9]*\\s(T)$")){ System.out.println("invalid dish"); } else if(match(s) == 2){ record = new Record(); record = JudgeRecord(s,menu); if(record!=null){ System.out.println(record.orderNum + " " + record.d.name + " " + record.getPrice()); t.order.addARecord1(record); } } else if(match(s) == 3){ orderNum = Integer.parseInt(strings[0]); t.order.delARecordByOrderNum(orderNum); } else if(s.matches("^(table)(.*?)$")){ if(t!=null){ tables.add(t); } t = new Table(); t = JudgeTable(s); if(t == null){ while(!"end".equals(s)){ s = input.nextLine(); if(s.matches("^(table)(.*?)$")){ t = JudgeTable(s); if(t != null){ break; } } else if("end".equals(s)){ break out; } } } } else if(match(s) == 5){ String str = strings[1]; for(int i=2;i<strings.length;i++){ str = str + " " + strings[i]; } num = Integer.parseInt(strings[0]); record = new Record(); record = JudgeRecord(str,menu); if(record!=null){ for(int i = 0; i < tables.size(); i++){ if(num == tables.get(i).num){ System.out.println(record.orderNum + " table " + t.num + " pay for table " + num + " " + record.getPrice()); tables.get(i).order.addARecord2(record); break; } } t.order.addARecord3(record); } } else{ System.out.println("wrong format"); } s = input.nextLine(); } if(t!=null){ tables.add(t); } int level1,level2,level3; for(int i = 0; i < tables.size(); i++){ level1 = tables.get(i).order.getavelevel("川菜"); level2 = tables.get(i).order.getavelevel("晋菜"); level3 = tables.get(i).order.getavelevel("浙菜"); tables.get(i).order.setnewrecords(resetrecords(tables.get(i).order.getRecords())); tables.get(i).out(); if(level1 != -1){ if(level1 == 0){ System.out.print(" 川菜 " + tables.get(i).order.getsunnum("川菜") + " 不辣"); } if(level1 == 1){ System.out.print(" 川菜 " + tables.get(i).order.getsunnum("川菜") + " 微辣"); } if(level1 == 2){ System.out.print(" 川菜 " + tables.get(i).order.getsunnum("川菜") + " 稍辣"); } if(level1 == 3){ System.out.print(" 川菜 " + tables.get(i).order.getsunnum("川菜") + " 辣"); } if(level1 == 4){ System.out.print(" 川菜 " + tables.get(i).order.getsunnum("川菜") + " 很辣"); } if(level1 == 5){ System.out.print(" 川菜 " + tables.get(i).order.getsunnum("川菜") + " 爆辣"); } } if(level2 != -1){ if(level2 == 0){ System.out.print(" 晋菜 " + tables.get(i).order.getsunnum("晋菜") + " 不酸"); } if(level2 == 1){ System.out.print(" 晋菜 " + tables.get(i).order.getsunnum("晋菜") + " 微酸"); } if(level2 == 2){ System.out.print(" 晋菜 " + tables.get(i).order.getsunnum("晋菜") + " 稍酸"); } if(level2 == 3){ System.out.print(" 晋菜 " + tables.get(i).order.getsunnum("晋菜") + " 酸"); } if(level2 == 4){ System.out.print(" 晋菜 " + tables.get(i).order.getsunnum("晋菜") + " 很酸"); } } if(level3 != -1){ if(level3 == 0){ System.out.print(" 浙菜 " + tables.get(i).order.getsunnum("浙菜") + " 不甜"); } if(level3 == 1){ System.out.print(" 浙菜 " + tables.get(i).order.getsunnum("浙菜") + " 微甜"); } if(level3 == 2){ System.out.print(" 浙菜 " + tables.get(i).order.getsunnum("浙菜") + " 稍甜"); } if(level3 == 3){ System.out.print(" 浙菜 " + tables.get(i).order.getsunnum("浙菜") + " 甜"); } } if(level3 == -1&&level2 == -1&&level1 == -1){ System.out.print(" "); } System.out.println(); } newtables = resettables(tables); newtables.sort(new MyComparator()); for(int i = 0; i < newtables.size(); i++){ if(i==(tables.size()-1)){ System.out.print(newtables.get(i).name + " " + newtables.get(i).tel + " " + newtables.get(i).sum); } else{ System.out.print(newtables.get(i).name + " " + newtables.get(i).tel + " " + newtables.get(i).sum); System.out.println(); } } } static class MyComparator implements Comparator<Table> { public int compare(Table t1, Table t2) { if(t1.name.compareToIgnoreCase(t2.name)>0){ return 1; } else if(t1.name.compareToIgnoreCase(t2.name)<0){ return -1; } else{ return 0; } } } static int match(String s){ String regex1 = "^[\u4e00-\u9fa5]{0,}\\s[1-9][0-9]*$"; String regex2 = "^[1-9][0-9]*\\s[\u4e00-\u9fa5]{0,}\\s\\d{1}\\s[1-9][0-9]*(\\s[1-9][0-9]*)*$"; String regex3 = "^\\d+\\s(delete)$"; String regex4 = "^(table)\\s[1-9][0-9]*\\s\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}/\\d{1,2}/\\d{1,2}$"; String regex5 = "^[1-9][0-9]*\\s[1-9][0-9]*\\s[\u4e00-\u9fa5]{0,}\\s\\d{1}\\s[1-9][0-9]*(\\s[1-9][0-9]*)*$"; if(s.matches(regex1)){ return 1; } else if(s.matches(regex2)){ return 2; } else if(s.matches(regex3)){ return 3; } else if(s.matches(regex4)){ return 4; } else if(s.matches(regex5)){ return 5; } else{ return 0; } } static Record JudgeRecord(String s,Menu menu){ String[] strings = s.split("[ /:]+"); int orderNum = Integer.parseInt(strings[0]); int portion; int num; Dish di = new Dish(); Record rec = new Record(); di = menu.searthDish(strings[1]); if(di == null){ return null; } else{ if(di.T){ int level = Integer.parseInt(strings[2]); portion = Integer.parseInt(strings[3]); num = Integer.parseInt(strings[4]); if("川菜".equals(di.cuisine)){ if(0<=level&&level<=5){ rec = new Record(orderNum,di,level,portion,num); return rec; } else{ System.out.println("spicy num out of range :" + level); return null; } } else if("晋菜".equals(di.cuisine)){ if(0<=level&&level<=4){ rec = new Record(orderNum,di,level,portion,num); return rec; } else{ System.out.println("acidity num out of range :" + level); return null; } } else if("浙菜".equals(di.cuisine)){ if(0<=level&&level<=3){ rec = new Record(orderNum,di,level,portion,num); return rec; } else{ System.out.println("acidity num out of range :" + level); return null; } } } else{ portion = Integer.parseInt(strings[2]); num = Integer.parseInt(strings[3]); rec = new Record(orderNum,di,-1,portion,num); return rec; } } return null; } static Table JudgeTable(String s){ if(!s.matches("^(table)\\s[1-9][0-9]*\\s:\\s[A-Za-z]{1,10}\\s(180|181|189|133|135|136)\\d{8}\\s\\d{4}/[1-9][0-9]?/[1-9][0-9]?\\s\\d{1,2}/\\d{1,2}/\\d{1,2}$")){ System.out.println("wrong format"); return null; } else{ String[] strings = s.split("[ /:]+"); int num = Integer.parseInt(strings[1]); int year = Integer.parseInt(strings[4]); int moon = Integer.parseInt(strings[5]); int day = Integer.parseInt(strings[6]); int hour = Integer.parseInt(strings[7]); int minute = Integer.parseInt(strings[8]); int second = Integer.parseInt(strings[9]); int d = hour*3600+minute*60+second; if(num<1||55<num){ System.out.println(num + " table num out of range"); return null; } try{ LocalDateTime localDateTime1 = LocalDateTime.of(year,moon,day,hour,minute,second); int n = localDateTime1.getDayOfWeek().getValue(); if(localDateTime1.isBefore(LocalDateTime.of(2022,1,1,0,0,0))||localDateTime1.isAfter(LocalDateTime.of(2023,12,31,0,0,0))){ System.out.println("not a valid time period"); return null; } else if((1<=n&&n<=5&&61200<=d&&d<=73800)||(1<=n&&n<=5&&37800<=d&&d<=52200)||(6<=n&&n<=7&&34200<=d&&d<=77400)){ System.out.println("table " + num + ": "); Table t1 = new Table(num,strings[2],strings[3],localDateTime1); return t1; } else{ System.out.println("table "+ num +" out of opening hours"); return null; } }catch(DateTimeException e){ System.out.println(num + " date error"); return null; } } } static ArrayList<Record> resetrecords(ArrayList<Record> records){ ArrayList<Record> recordss = new ArrayList<>(); ArrayList<Record> newrecords = new ArrayList<>(); for(int i = 0; i < records.size(); i++){ if(!records.get(i).isdai){ recordss.add(records.get(i)); } } for(int i = 0; i < recordss.size(); i++){ Record re = new Record(recordss.get(i).d,recordss.get(i).portion,recordss.get(i).num); for(int j = i+1; j < recordss.size(); j++){ if(recordss.get(i).portion==recordss.get(j).portion&&recordss.get(i).d.name==recordss.get(j).d.name){ re.num = re.num + recordss.get(j).num; recordss.remove(j); j--; } } newrecords.add(re); } recordss.removeAll(recordss); return newrecords; } static ArrayList<Table> resettables(ArrayList<Table> tables){ ArrayList<Table> tabless = new ArrayList<>(); ArrayList<Table> newtables = new ArrayList<>(); for(int i = 0; i < tables.size(); i++){ tabless.add(tables.get(i)); } for(int i = 0; i < tabless.size(); i++){ Table ta = new Table(tabless.get(i).num,tabless.get(i).name,tabless.get(i).tel,tabless.get(i).localDateTime,tabless.get(i).order); ta.sum = ta.sum + ta.order.getTotalPrice1(ta.localDateTime); for(int j = i+1; j < tabless.size(); j++){ if(ta.name.equals(tabless.get(j).name)){ ta.sum = ta.sum + tabless.get(j).order.getTotalPrice1(tabless.get(j).localDateTime); tabless.remove(j); j--; } } newtables.add(ta); } tabless.removeAll(tabless); return newtables; } }
期中考试 7-3 测验3-继承与多态
抽象出Shape父类(抽象类),Circle及Rectangle作为子类,类图如下所示:
试编程完成如上类图设计,主方法源码如下(可直接拷贝使用):
public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); int choice = input.nextInt(); switch(choice) { case 1://Circle double radiums = input.nextDouble(); Shape circle = new Circle(radiums); printArea(circle); break; case 2://Rectangle double x1 = input.nextDouble(); double y1 = input.nextDouble(); double x2 = input.nextDouble(); double y2 = input.nextDouble(); Point leftTopPoint = new Point(x1,y1); Point lowerRightPoint = new Point(x2,y2); Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint); printArea(rectangle); break; } }其中,
printArea(Shape shape)方法为定义在Main类中的静态方法,体现程序设计的多态性。输入格式:
输入类型选择(1或2,不考虑无效输入)
对应图形的参数(圆或矩形)输出格式:
图形的面积(保留两位小数)
输入样例1:
1 5.6输出样例1:
在这里给出相应的输出。例如:
98.52输入样例2:
2 5.6 -32.5 9.4 -5.6输出样例2:
在这里给出相应的输出。例如:
102.22
import java.util.Scanner; class Shape{ public Shape(){ } public double getArea(){ return 0; } } class Point{ double x1; double y1; public Point(double x1,double y1){ this.x1 = x1; this.y1 = y1; } public double getX(){ return x1; } public double getY(){ return y1; } } class Circle extends Shape{ double radiums; public Circle(double radiums){ this.radiums = radiums; } public double getArea(){ if(radiums<=0){ return -1; } else{ return Math.PI*this.radiums*this.radiums; } } } class Rectangle extends Shape{ Point leftTopPoint; Point lowerRightPoint; public Rectangle(Point leftTopPoint,Point lowerRightPoint){ this.leftTopPoint = leftTopPoint; this.lowerRightPoint = lowerRightPoint; } public double getArea(){ return Math.abs((leftTopPoint.getX()-lowerRightPoint.getX())*(leftTopPoint.getY()-lowerRightPoint.getY())); } } public class Main { static void printArea(Shape shape){ double s = shape.getArea(); if(s<0){ System.out.println("Wrong Format"); } else{ System.out.print(String.format("%.2f",s)); } } public static void main(String[] args) { Scanner input = new Scanner(System.in); int choice = input.nextInt(); switch(choice) { case 1://Circle double radiums = input.nextDouble(); Shape circle = new Circle(radiums); printArea(circle); break; case 2://Rectangle double x1 = input.nextDouble(); double y1 = input.nextDouble(); double x2 = input.nextDouble(); double y2 = input.nextDouble(); Point leftTopPoint = new Point(x1,y1); Point lowerRightPoint = new Point(x2,y2); Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint); printArea(rectangle); break; } } }
三.踩坑心得:
7-2 单词统计与排序:可以使用Comparator接口使代码更简洁
7-3 判断两个日期的先后,计算间隔天数、周数:要注意输入的格式不能用Java中的日期类简单判断合不合法而判断两个日期的先后则只需判断合不合法就够了,计算间隔天数、周数,还要注意第二行两个日期相等时的输出否则会答案错误,只要熟练运用日期类就好了
7-1 菜单计价程序-4:由于输入的操作过于复杂,容易导致没有样例不知道bug出在哪里,其中桌的时间使用日期类能够简单许多,最重要的是最后计算原价和打折后的价要准确否则对不了多少
7-1 菜单计价程序-5:相比于 菜单计价程序-4要简单许多,但也需要注意用户输出时要对其订单进行合并计价后再输出,特色菜多了味道,多加一个String的属性就好了
四.主要困难以及改进建议
由于刚接触Java,遇到的主要困难还是不熟悉Java的一些语法,类等以后多写代码就好了,写代码时要注重规范,不要为了省事而不去定义方法,类并且省略注释否则调试代码的时间可能会比写代码的时间长。如对用户和桌号进行合并直接在主类中去操作容易导致数据紊乱,对输入进行操作直接在主类中会导致代码比较乱,难以修改。我觉得以后没必要为了省事而不去定义方法,多定义方法可以使代码更简单易懂
五.总结:1.在这三次作业中,我发现自己代码的逻辑性不够好,从圈复杂度高这一特点可以看出存在太多不必要的代码了。逻辑不清晰导致代码冗长,代码质量不高。
2.经过这几次作业后,我已对java有了一个更深的了解以及掌握,尤其是对类的定义,使用,创建,还有类与类的关系。
3.经过这段时间的java学习我对java的语法与c语言的不同有了更多的了解,比如c语言的指针、地址、数组储存方式与java都不同,在今后的学习中我更应体会其中的不同之处,避免c语言对java学习的影响。
4.遇到问题时,通过调试逐步找到问题所在,然后这三次作业中我仍然发现自己存在着许多的语法错误,在今后的学习中更应加强基础知识的学习,吃透书本中的内容及课堂中所学知识。
5.这几次作业给我最大的感触就是遇到问题就应该大胆地去猜测,有想法就用代码表示出来,多加调试验证自己的想法,编程就应该要以动手实践为主,不尝试就不知道可不可行。











浙公网安备 33010602011771号