南航航空大学第二次BLOG
前言
这次从第一次题目难度开始,后面的数次难度激增,我也只有第一次全部写完pta的所有题目,后面就没有拿到过满分。但总体来说,主要知识点还是在设计类和学习java语言,以及用面向对象的思维方式。Java面向对象比c++更模块化,思维方式也不一样。对只接触过一点java语言的我们还是很有挑战的。还有一次期中考试,虽然难度不算大,但考察的内容很全面。
设计与分析
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+英文空格+桌号+“:”+英文空格+当前桌的总价
本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。
复杂度分析


类图

个人认为这是菜单系列的开端,后面的4和5都是在这一次的基础上进行的修改,并且这次的难度相对简单,代码结构相对清晰,在写的过程中没有遇到特别棘手的问题。
代码如下:
点击查看代码
import java.util.Scanner;
import java.util.Calendar;
class Dish {
String name;
int unit_price;
int getPrice(int portion) {
int price = 0;
if (portion == 1) {
price = unit_price;
} else if (portion == 2) {
price = Math.round((float) (unit_price * 1.5));
} else if (portion == 3) {
price = (unit_price * 2);
}
return price;
}
}
class Menu {
Dish[] dishes = new Dish[10];
int count = 0;
Dish searchDish(String dishName) {
Dish temp = null;
for (int i = count - 1; i >= 0; i--) {
if (dishName.equals(dishes[i].name)) {
temp = dishes[i];
break;
}
}
if (temp == null) {
System.out.println(dishName + " does not exist");
}
return temp;
}
Dish addDish(String dishName, int unit_price) {
Dish dish = new Dish();
dish.name = dishName;
dish.unit_price = unit_price;
count++;
return dish;
}
}
class Record {
int orderNum;
Dish dish = new Dish();
int num = 0;
int portion;
int getPrice() {
return dish.getPrice(portion) * num;
}
}
class Order {
Record[] records = new Record[10];
int count = 0; // 订单数量
void addRecord(int orderNum, String dishName, int portion, int num) {
records[count] = new Record();
records[count].dish.name = dishName;
records[count].orderNum = orderNum;
records[count].portion = portion;
records[count].num = num;
count++;
}
int deleteRecordByOrderNum(int orderNum) {
if (orderNum > count || orderNum <= 0) {
System.out.println("delete error;");
return 0;
} else {
return records[orderNum - 1].getPrice();
}
}
}
class Table {
int tableNum;
String tableDtime;
int year, month, day, week, hh, mm, ss;
int sum = 0;
Order order = new Order();
float discount = -1;
void getTotalPrice() {
if (discount > 0) {
sum = Math.round(sum * discount);
System.out.println("table " + tableNum + ": " + sum);
} else {
System.out.println("table " + tableNum + " out of opening hours");
}
}
void preProcess(String tableDtime) {
this.tableDtime = tableDtime;
processTime();
applyDiscount();
}
void processTime() {
String[] temp = tableDtime.split(" ");
tableNum = Integer.parseInt(temp[1]);
String[] temp1 = temp[2].split("/");
String[] temp2 = temp[3].split("/");
year = Integer.parseInt(temp1[0]);
month = Integer.parseInt(temp1[1]);
day = Integer.parseInt(temp1[2]);
Calendar c = Calendar.getInstance();
c.set(year, (month - 1), day);
week = c.get(Calendar.DAY_OF_WEEK);
if (week == 1)
week = 7;
else
week--;
hh = Integer.parseInt(temp2[0]);
mm = Integer.parseInt(temp2[1]);
ss = Integer.parseInt(temp2[2]);
}
void applyDiscount() {
if (week >= 1 && week <= 5) {
if (hh >= 17 && hh < 20)
discount = 0.8F;
else if (hh == 20 && mm < 30)
discount = 0.8F;
else if (hh == 20 && mm == 30 && ss == 0)
discount = 0.8F;
else if (hh >= 11 && hh <= 13 || hh == 10 && mm >= 30)
discount = 0.6F;
else if (hh == 14 && mm < 30)
discount = 0.6F;
else if (hh == 14 && mm == 30 && ss == 0)
discount = 0.6F;
} else {
if (hh >= 10 && hh <= 20)
discount = 1.0F;
else if (hh == 9 && mm >= 30)
discount = 1.0F;
else if (hh == 21 && mm < 30 || hh == 21 && mm == 30 && ss == 0)
discount = 1.0F;
}
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Menu menu = new Menu();
Table[] tables = new Table[10];
int menuCount = 0; // 菜单数
int orderCount = 0; // 订单数
Dish tempDish;
int tableNum = 0; // 桌号
int count;
String[] temp;
int a1, a2, a3, a4, a5;
while (true) {
String st = sc.nextLine();
temp = st.split(" ");
if (st.equals("end"))
break;
count = temp.length;
if (count == 2) {
if (temp[1].equals("delete")) {
a1 = Integer.parseInt(temp[0]);
int c = tables[tableNum].order.deleteRecordByOrderNum(a1);
tables[tableNum].sum -= c;
} else {
a2 = Integer.parseInt(temp[1]);
menu.dishes[menuCount] = menu.addDish(temp[0], a2);
menuCount++;
}
} else if (count == 4) {
if (temp[0].equals("table")) {
tableNum++;
orderCount = 0;
tables[tableNum] = new Table();
tables[tableNum].preProcess(st);
System.out.println("table " + tableNum + ": ");
} else {
a3 = Integer.parseInt(temp[0]);
a4 = Integer.parseInt(temp[2]);
a5 = Integer.parseInt(temp[3]);
tables[tableNum].order.addRecord(a3, temp[1], a4, a5);
tempDish = menu.searchDish(temp[1]);
if (tempDish != null) {
tables[tableNum].order.records[orderCount].dish = tempDish;
int a = tables[tableNum].order.records[orderCount].getPrice();
System.out.println(tables[tableNum].order.records[orderCount].orderNum + " " + tempDish.name + " " + a);
tables[tableNum].sum += a;
}
orderCount++;
}
} else if (count == 5) {
a1 = Integer.parseInt(temp[1]);
a2 = Integer.parseInt(temp[3]);
a3 = Integer.parseInt(temp[4]);
tables[tableNum].order.addRecord(a1, temp[2], a2, a3);
tempDish = menu.searchDish(temp[2]);
if (tempDish != null) {
tables[tableNum].order.records[orderCount].dish.unit_price = tempDish.unit_price;
int b = tables[tableNum].order.records[orderCount].getPrice();
System.out.println(temp[1] + " table " + tables[tableNum].tableNum + " pay for table " + temp[0] + " " + b);
tables[tableNum].sum += b;
}
orderCount++;
}
}
for (int i = 1; i < tableNum + 1; i++) {
tables[i].getTotalPrice();
}
}
}
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+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价
复杂度分析


类图

代码的主要功能是实现餐厅点餐系统的各种操作,包括添加菜品、点餐记录、订单,计算价格等。
具体分析如下:
-
Dish类:表示菜品,包含菜品名称、是否是特色菜、单价等属性,以及计算菜品价格的方法。
-
Menu类:表示菜单,包含一个菜品数组,保存所有菜品信息。有添加菜品和查找菜品的方法。
-
Record类:表示点餐记录,包含订单序号、菜品、数量、份额等属性,以及计算价格的方法。还有一些用于检查输入数据是否合法的方法。
-
Order类:表示订单,包含一个点餐记录数组,保存订单上的每一道菜品记录。有添加记录、删除记录和计算订单总价的方法。
-
Table类:表示桌子,包含桌号、是否有效、点餐时间、订单总价等属性。有处理时间、计算折扣、检查是否需要合并计算等方法。
-
Main类:主类,包含main方法,用于接收用户输入并进行相应的操作。通过Scanner类获取用户输入的指令,根据指令调用相应的方法进行处理。
这一题难度较大,我是参考其他的代码写的,自己在做的时候没有理清逻辑,导致测试点很多无法通过,在研究了他人的代码后,多少理解了一点题目。值得注意的是,在筛选时用了正则表达式。
代码如下:
点击查看代码
import java.util.Scanner;
import java.util.Calendar;
import java.time.YearMonth;
class Dish {
String name;//菜品名称
boolean isSpecial = false;//是不是特色菜
int unit_price; //单价
boolean exist = true;
//int num;
int getPrice(int portion) {
int peic = 0;
if (portion == 1) {
peic = unit_price ;
} else if (portion == 2) {
peic = Math.round((float) (unit_price * 1.5)) ;
} else if (portion == 3) {
peic = (unit_price * 2) ;
}
return peic;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}
}
class Menu {
Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息
int count = 0;
Dish searthDish(String dishName){
Dish temd = null;
for(int i=count-1;i>=0;i--){
if(dishName.equals(dishs[i].name)&&dishs[i].exist){
temd = dishs[i];
break;
}
}
if(temd==null){
System.out.println(dishName+" does not exist");
}
return temd;
}//根据菜名在菜谱中查找菜品信息,返回Dish对象。
Dish addDish(String dishName,int unit_price){
Dish dh = new Dish();
dh.name = dishName;
dh.unit_price = unit_price;
count++;
if(unit_price<1||unit_price>300) {
dh.exist = false;
System.out.println(dishName+" price out of range "+unit_price);
}
return dh;
}//添加一道菜品信息
}
class Record {
int orderNum;//序号\
Dish d = new Dish();//菜品\
int num = 0;
int portion;//份额(1/2/3代表小/中/大份)\
boolean noNeed = true;
int exist = 1;
float realdiscnt = 1;
//int asum = 0;
boolean isTaked = false;//是否是给别人点的
int getPrice(){
return Math.round(d.getPrice(portion)*num);
}//计价,计算本条记录的价格\
float Checkportion(float discnt){//数量输入检查,计算价格
if(portion>3||portion<1) {
System.out.println(orderNum + " portion out of range " + portion);
exist = 0;
noNeed = false;
}else if(num<1||num>15) {
System.out.println(orderNum + " num out of range" +" "+num);
exist = 0;
noNeed = false;
}else{
if(d.isSpecial)
if(discnt==0.8F||discnt==0.6F)
realdiscnt = 0.7F;
if(exist==1&&!isTaked) {
System.out.println(orderNum + " " + d.name + " " + getPrice());
}
}
return realdiscnt;
}
boolean Checkahead(){
if(num<1||num>15) {
return false;
}else return portion <= 3 && portion >= 1;
}
}
class Order {
Record[] records = new Record[100];//保存订单上每一道的记录
int count = 0;//订单数量
int getTotalPrice(){
int sum=0;
for(int i=0;i<count;i++){
if(records[i].exist==0)
continue;
sum=sum+records[i].getPrice();
}
return sum;
}//计算订单的总价
Record addARecord(int orderNum, String dishName, int portion, int num){
boolean flag = true;
for(int i=0;i<count;i++){//不能点份额一样的菜
if (records[i].d.name.equals(dishName) && records[i].portion == portion) {
flag = false;
break;
}
}
count++;
records[count] = new Record();
records[count].d.name = dishName;
records[count].orderNum = orderNum;
records[count].portion = portion;
records[count].num = num;
records[count].noNeed = flag;
return records[count];
}//添加一条菜品信息到订单中。
Record TakeOdfor(int mynum,Table[] table, int AnotherNum, int orderNum, String dishName, int portion, int num){
boolean flag = false;
for(Table t : table) {
if(t==null)
continue;
if (t.tableNum != mynum&&t.tableNum==AnotherNum) {
flag = true;
break;
}
}
if(flag) {
count++;
records[count] = new Record();
records[count].d.name = dishName;
records[count].orderNum = orderNum;
records[count].portion = portion;
records[count].num = num;
return records[count];
}else{
System.out.println("Table number :" + AnotherNum + " does not exist");
return null;
}
}
void delARecordByOrderNum(int orderNum){
if(orderNum>count||orderNum<=0){
System.out.println("delete error;");
}else {
if(records[orderNum-1].exist==0) {
System.out.println("deduplication "+orderNum);
return;
}
records[orderNum-1].exist = 0;
}
}//根据序号删除一条记录
}
class Table {
int tableNum;
boolean inputIsvalid = false;
boolean istoSum = false;//判断是否要合并计算
String tableDtime;
int year,month,day,week,hh,mm,ss;
int sum = 0;//一桌价格 ;
int primesum = 0;
Order odt = new Order();
float discnt = -1;
float rediscnt = 1;
void Gettottalprice(){
if(discnt>0){
primesum = odt.getTotalPrice();
if(primesum==0)
sum=0;
System.out.println("table " + tableNum + ": " +primesum+" "+sum);
}
}
void AheadProcess(String tableDtime){
this.tableDtime = tableDtime;
processTime();
discount();
}
void processTime(){//处理时间
String[] temp = tableDtime.split(" ");
tableNum = Integer.parseInt(temp[1]);
String[] temp1 = temp[2].split("/");
String[] temp2 = temp[3].split("/");
year = Integer.parseInt(temp1[0]);
month = Integer.parseInt(temp1[1]);
day = Integer.parseInt(temp1[2]);
Calendar c = Calendar.getInstance();
c.set(year, (month-1), day);
week = c.get(Calendar.DAY_OF_WEEK);
if(week==1)
week = 7;
else
week--;
hh = Integer.parseInt(temp2[0]);
mm = Integer.parseInt(temp2[1]);
ss = Integer.parseInt(temp2[2]);
}
boolean DateisValid(){
if(year<1000)
return false;
if(month<1||month>12)
return false;
YearMonth mytime = YearMonth.of(year,month);
return mytime.isValidDay(day);
}
boolean Daterande(){
boolean flag = year >= 2022 && year <= 2023;
if(!flag){
System.out.println("not a valid time period");
inputIsvalid = false;
}
return flag;
}
void discount(){
if(week>=1&&week<=5)
{
if(hh>=17&&hh<20)
discnt=0.8F;
else if(hh==20&&mm<30)
discnt=0.8F;
else if(hh==20&&mm==30&&ss==0)
discnt=0.8F;
else if(hh>=11&&hh<=13||hh==10&&mm>=30)
discnt=0.6F;
else if(hh==14&&mm<30)
discnt=0.6F;
else if(hh==14&&mm==30&&ss==0)
discnt=0.6F;
}
else
{
if(hh>=10&&hh<=20)
discnt= 1.0F;
else if(hh==9&&mm>=30)
discnt= 1.0F;
else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
discnt= 1.0F;
}
}
boolean CheckSameTime(Table table){
if(tableNum!=table.tableNum)
return false;
if(week==table.week&&week>=1&&week<=5){
return discnt == table.discnt;
}else if(week==table.week&&week==6||week==7){
int subtime = hh*3600+mm*60+ss-table.hh*3600-table.mm*60-ss;
return Math.abs(subtime) < 3600;
}
return false;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Menu mu = new Menu();
Table[] tablemes = new Table[57];//桌号1-55;
int j = 0;//菜单数
int l = 0;//订单数
//代点菜数
//遍历桌
int cntTab = 0;//桌号
String[] temp;//字符串存储
int tempordernum = 0;//临时存上一个有效序号
String input;
String regex = "[\\u4e00-\\u9fa5]* \\d*";//非特色菜菜谱
String regex1 = "[\\u4e00-\\u9fa5]* \\d* T";//特色菜谱
String regex2 = "\\d (delete)";//删除情况
String regex3 = "(table) ([1-4][0-9]*|5[0-5]*) \\d{4}/\\d+/\\d{1,2} ([0-1]?[0-9]|2[0-3])/([0-5][0-9])/([0-5][0-9])";//添桌子的情况
String regex4 = "([1-9]|[1-9][0-9]*) [\\u4e00-\\u9fa5]+ \\d+ \\d+";//点菜记录的添加;
String regex5 = "([1-4][0-9]*|5[0-5]*|[1-9]) \\d [\\u4e00-\\u9fa5]+ [123] (1[0-5]|[1-9])";//代点菜
while (true) {
int count;//空格数量;
input = sc.nextLine();//获取输入,每行
if(input.equals("end"))
break;
if(input.isEmpty()) {
System.out.println("wrong format");
continue;
}
temp = input.split(" ");//分割
/*
* 判断输入的类型*/
count = temp.length;
if(count==2){//非特色菜菜谱,或者删除菜;
if(input.matches(regex2)){//删除的情况桌子有效才删除
if (tablemes[cntTab] != null && tablemes[cntTab].inputIsvalid) {
tablemes[cntTab].odt.delARecordByOrderNum(Integer.parseInt(temp[0]));//删除
}
}else if(input.matches(regex)){//非特色菜谱添加
if (cntTab == 0) {
mu.dishs[j] = new Dish();
mu.dishs[j] = mu.addDish(temp[0], Integer.parseInt(temp[1]));
j++;
} else if(tablemes[cntTab].inputIsvalid){
System.out.println("invalid dish");
}
}else {
System.out.println("wrong format");
}
}else if(count==3){//特色菜菜谱
if(input.matches(regex1)) {
if(cntTab!=0) {
if(tablemes[cntTab].inputIsvalid)
System.out.println("invalid dish");
else
continue;
}
mu.dishs[j] = new Dish();
mu.dishs[j] = mu.addDish(temp[0], Integer.parseInt(temp[1]));
mu.dishs[j].isSpecial = true;//是特色菜
j++;
}else
System.out.println("wrong format");
}
//桌子的添加,点菜记录的添加,
else if(temp[0].equals("table")||input.contains("/")) {
cntTab++;
tablemes[cntTab] = new Table();
if(temp[0].equals("table")){
if(input.matches(regex3))
tablemes[cntTab].AheadProcess(input);
tablemes[cntTab].inputIsvalid=true;
if (input.matches(regex3)) {
if(tablemes[cntTab].inputIsvalid&&!tablemes[cntTab].DateisValid()){//检查日期
System.out.println(tablemes[cntTab].tableNum+" date error");
tablemes[cntTab].inputIsvalid=false;
continue;
}
if(tablemes[cntTab].inputIsvalid&&!tablemes[cntTab].Daterande()){
tablemes[cntTab].inputIsvalid=false;
continue;
}
for(int i =1;i<cntTab;i++){
if (tablemes[i].inputIsvalid && tablemes[cntTab].CheckSameTime(tablemes[i])) {//同一时间段
tablemes[cntTab].istoSum = true;
} else {
l = 0;
}
tempordernum = 0;
}
if(tablemes[cntTab].discnt>0)
System.out.println("table " + tablemes[cntTab].tableNum + ": ");
else {
System.out.println("table " + tablemes[cntTab].tableNum + " out of opening hours");
tablemes[cntTab].inputIsvalid = false;
}
continue;
} else {//第一个是table但不合法
tablemes[cntTab].inputIsvalid = false;
if(!temp[1].isEmpty() &&temp[1].charAt(0)>='1'&&temp[1].charAt(0)<='9'&&!temp[1].contains("/")){
if(Integer.parseInt(temp[1])<1||Integer.parseInt(temp[1])>55){
System.out.println(Integer.parseInt(temp[1])+" table num out of range");
continue;
}
}
}
}
System.out.println("wrong format");
tablemes[cntTab].inputIsvalid = false;
if(!temp[0].equals("table"))
tablemes[cntTab].istoSum = true;
}else if(count==4){
if (tablemes[cntTab] != null && input.matches(regex4) && (tablemes[cntTab].inputIsvalid || tablemes[cntTab].istoSum)) {//点菜记录
Dish tem;
int aheadcntTab = cntTab - 1;
if (!tablemes[cntTab].istoSum) {//不需要合并
tablemes[cntTab].odt.records[l] = new Record();
tablemes[cntTab].odt.records[l] = tablemes[cntTab].odt.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3]));
if (l - 1 >= 0) {//判断记录序号是否递增
tempordernum = getTempordernum(tablemes, l, cntTab, temp, tempordernum);
} else {//特殊情况
if (tablemes[cntTab].odt.records[l].Checkahead())
tempordernum = tablemes[cntTab].odt.records[l].orderNum;
}
if ((tem = mu.searthDish(temp[1])) != null) {
float temdiscnt;//临时储存折扣
tablemes[cntTab].odt.records[l].d = tem;
temdiscnt = tablemes[cntTab].odt.records[l].Checkportion(tablemes[cntTab].discnt);
if (temdiscnt != 1F)
tablemes[cntTab].rediscnt = temdiscnt;//最终折扣
if (tablemes[cntTab].odt.records[l].exist == 1 && tablemes[cntTab].odt.records[l].noNeed) {
if (tablemes[cntTab].rediscnt != 1) {
tablemes[cntTab].sum += Math.round(tablemes[cntTab].odt.records[l].getPrice() * tablemes[cntTab].rediscnt);
tablemes[cntTab].rediscnt = 1.0F;
} else
tablemes[cntTab].sum += Math.round(tablemes[cntTab].odt.records[l].getPrice() * tablemes[cntTab].discnt);
}
}
if (!tablemes[cntTab].istoSum) {//如果份额名字未重复;
l++;
}
} else {//需要合并计算
tablemes[aheadcntTab].odt.records[l] = new Record();
tablemes[aheadcntTab].odt.records[l] = tablemes[aheadcntTab].odt.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3]));
if (l - 1 >= 0) {//判断记录序号是否递增
tempordernum = getTempordernum(tablemes, l, aheadcntTab, temp, tempordernum);
}
if ((tem = mu.searthDish(temp[1])) != null) {
float temdiscnt;//临时储存折扣
tablemes[aheadcntTab].odt.records[l].d = tem;
temdiscnt = tablemes[aheadcntTab].odt.records[l].Checkportion(tablemes[aheadcntTab].discnt);//计算折扣
if (temdiscnt == 0.7F)//如果需要调整
tablemes[aheadcntTab].rediscnt = temdiscnt;//最终折扣//更改折扣
if (tablemes[aheadcntTab].odt.records[l].exist == 1) {//必须存在
if (tablemes[aheadcntTab].rediscnt != 1) {
tablemes[aheadcntTab].sum += Math.round(tablemes[aheadcntTab].odt.records[l].getPrice() * tablemes[aheadcntTab].rediscnt);
tablemes[aheadcntTab].rediscnt = 1.0F;
} else
tablemes[aheadcntTab].sum += Math.round(tablemes[aheadcntTab].odt.records[l].getPrice() * tablemes[cntTab].discnt) - 1;
}
}
l++;
}
}
}
else if (tablemes[cntTab] != null && count == 5 && tablemes[cntTab].inputIsvalid) {//代点菜
int temSum = 0;
if (input.matches(regex5)) {
int AnothNum = Integer.parseInt(temp[0]);
tablemes[cntTab].odt.records[l] = tablemes[cntTab].odt.TakeOdfor(tablemes[cntTab].tableNum, tablemes, AnothNum, Integer.parseInt(temp[1]), temp[2], Integer.parseInt(temp[3]), Integer.parseInt(temp[4]));
Dish tem;
if ((tem = mu.searthDish(temp[2])) != null && tablemes[cntTab].odt.records[l] != null) {
tablemes[cntTab].odt.records[l].isTaked = true;//给别人diade
float temdiscnt;//临时储存折扣
tablemes[cntTab].odt.records[l].d = tem;
temdiscnt = tablemes[cntTab].odt.records[l].Checkportion(tablemes[cntTab].discnt);
if (temdiscnt != 1F)
tablemes[cntTab].rediscnt = temdiscnt;//最终折扣
if (tablemes[cntTab].odt.records[l].exist == 1 && tablemes[cntTab].odt.records[l].noNeed) {
if (tablemes[cntTab].rediscnt != 1) {
tablemes[cntTab].sum += Math.round((temSum = tablemes[cntTab].odt.records[l].getPrice()) * tablemes[cntTab].rediscnt);
tablemes[cntTab].rediscnt = 1.0F;
} else
tablemes[cntTab].sum += Math.round((temSum = tablemes[cntTab].odt.records[l].getPrice()) * tablemes[cntTab].discnt);
}
System.out.println(temp[1] + " table " + tablemes[cntTab].tableNum + " pay for table " + temp[0] + " " + temSum);
}
if (tablemes[cntTab].odt.records[l] != null)
l++;
} else
System.out.println("wrong format");
}
}
for(int i=1;i<=cntTab;i++){
if(tablemes[i].inputIsvalid&&!tablemes[i].istoSum)
tablemes[i].Gettottalprice();
}
}
private static int getTempordernum(Table[] tablemes, int l, int cntTab, String[] temp, int tempordernum) {
if (Integer.parseInt(temp[0]) <= tempordernum) {
System.out.println("record serial number sequence error");
tablemes[cntTab].odt.records[l].exist = 0;
} else if (tablemes[cntTab].odt.records[l] != null && tablemes[cntTab].odt.records[l].noNeed)
tempordernum = tablemes[cntTab].odt.records[l].orderNum;
return tempordernum;
}
}
3.菜单计价程序-5
题目要求如下
以上为菜单计价系列-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+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格
最后按拼音顺序输出每位客户(不考虑客户同名或拼音相同的情况)的支付金额,格式: 用户姓名+英文空格+手机号+英文空格+支付总金额,按输入顺序排列。
复杂度分析


类图

-
首先定义了一个Dish类,表示菜品。菜品有名称(name)、单价(unitPrice)和类型(type)属性。菜品类型使用枚举类DishType表示,包括川菜(Chuan)、晋菜(Jin)和浙菜(Zhe)。
-
然后定义了一个Menu类,表示菜单。菜单中可以添加菜品(addDish),并且可以根据菜品名称查找菜品(searchDish)。
-
接着定义了一个Record类,表示订单中的一条记录。记录包含订单号(orderNum)、菜品(dish)、份数(portion)、数量(quantity)、口味等级(level)、是否合法(flag)和赠送的桌号(givenId)等属性。记录还有计算价格的方法(getPrice)和打印信息的方法(print)。
-
然后定义了一个Table类,表示餐桌。餐桌有桌号(tableId)、客人姓名(name)、联系电话(phone)、就餐日期(date)、就餐时间(time)、是否合法(flag)等属性。餐桌可以根据就餐时间计算折扣系数(getCoefficient),计算总价(getTotalPrice)和应付金额(getCheckedPrice),获取平均口味等级(getAveLevel),添加订单记录(addRecord),删除订单记录(delRecordByOrderNum),打印餐桌信息(printId、printInfo)等。
-
最后在主函数中,通过Scanner类获取用户输入。创建菜单(menu)、餐桌(tables)和临时菜品(tempDish)等变量。根据用户输入的指令进行相应的操作,包括添加菜品、添加订单记录、删除订单记录等。最后输出每个餐桌的信息和客人的消费金额。
菜单5依旧是在菜单3的基础上进行了修改,但是难度依旧不小,我也是参考了别人的代码,但还是没能完全达到题目的要求拿到满分。
代码如下:
点击查看代码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) throws ParseException {
Menu menu = new Menu();
// 读入菜单信息
Scanner scanner = new Scanner(System.in);
String menuLine = scanner.nextLine();
while (!menuLine.startsWith("table")) {
String[] menuInfo = menuLine.split(" ");
if (menuInfo.length == 2) {
String name = menuInfo[0];
int unitPrice = Integer.parseInt(menuInfo[1]);
if (menu.searchDish(name) == null) {
menu.addDish(name, unitPrice);
}
} else if (menuInfo.length == 4 && menuLine.endsWith("T")) {
String name = menuInfo[0];
String type = menuInfo[1];
int unitPrice = Integer.parseInt(menuInfo[2]);
Map<String, String> map = new HashMap<>() {
{
put("川菜", "Chuan");
put("晋菜", "Jin");
put("浙菜", "Zhe");
}
};
DishType dishType = DishType.valueOf(map.get(type));
if (menu.searchDish(name) == null) {
menu.addDish(name, unitPrice, dishType);
}
} else {
System.out.println("wrong format");
}
menuLine = scanner.nextLine();
}
ArrayList<Table> tables = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
// 读入订单信息
int tableId = 0;
String name;
String phone;
Date date;
Date time;
boolean legalTime = true;
boolean legalFormat = true;
String orderLine = menuLine;
while (!orderLine.equals("end")) {
String[] orderInfo = orderLine.split(" ");
// 解析桌号标识
if (orderLine.startsWith("table")) {
legalFormat = true;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat timeFormat = new SimpleDateFormat("HH/mm/ss");
tableId = Integer.parseInt(orderInfo[1]);
name = orderInfo[3];
phone = orderInfo[4];
try {
date = dateFormat.parse(orderInfo[5]);
time = timeFormat.parse(orderInfo[6]);
} catch (Exception e) {
legalFormat = false;
System.out.println("wrong format");
orderLine = scanner.nextLine();
continue;
}
String regex = "^1(80|81|89|33|35|36)\\d{8}$";
Table table = new Table(tableId, name, phone, date, time);
tables.add(table);
if (name.length() > 10 || !phone.matches(regex)) {
legalFormat = false;
System.out.println("wrong format");
orderLine = scanner.nextLine();
continue;
}
if (!names.contains(name)) {
names.add(name);
}
if (table.getCoefficient(true) == 0) {
legalTime = false;
System.out.println("table " + table.getTableId() + " out of opening hours");
} else {
System.out.println(table.printId());
}
} else {
if (legalFormat) {
int orderNum;
try {
orderNum = Integer.parseInt(orderInfo[0]);
} catch (Exception e) {
System.out.println("wrong format");
orderLine = scanner.nextLine();
continue;
}
if (orderLine.endsWith("delete")) {
if (!tables.get(tableId - 1).delRecordByOrderNum(orderNum)) {
System.out.println("delete error");
}
} else {
if (orderInfo.length == 4) {
String dishName = orderInfo[1];
int portion = Integer.parseInt(orderInfo[2]);
int quantity = Integer.parseInt(orderInfo[3]);
Dish dish = menu.searchDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
orderLine = scanner.nextLine();
continue;
}
Record record = new Record(tableId, orderNum, dish, portion, quantity);
tables.get(tableId - 1).addRecord(record);
if (legalTime) {
System.out.println(record.print(tableId));
}
} else if (orderInfo.length == 5) {
String dishName = orderInfo[1];
int level = Integer.parseInt(orderInfo[2]);
int portion = Integer.parseInt(orderInfo[3]);
int quantity = Integer.parseInt(orderInfo[4]);
Dish dish = menu.searchDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
orderLine = scanner.nextLine();
continue;
}
Record record = new Record(tableId, orderNum, dish, level, portion, quantity);
tables.get(tableId - 1).addRecord(record);
if (legalTime) {
System.out.println(record.print(tableId));
}
} else if (orderInfo.length == 6) {
int givenId = Integer.parseInt(orderInfo[1]);
String dishName = orderInfo[2];
int level = Integer.parseInt(orderInfo[3]);
int portion = Integer.parseInt(orderInfo[4]);
int quantity = Integer.parseInt(orderInfo[5]);
Dish dish = menu.searchDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
orderLine = scanner.nextLine();
continue;
}
Record record1 = new Record(givenId, orderNum, dish, level, portion, quantity);
Record record2 = new Record(givenId, orderNum, dish, level, 0, quantity);
tables.get(tableId - 1).addRecord(record1);
tables.get(givenId - 1).addRecord(record2);
if (legalTime) {
System.out.println(record1.print(tableId));
}
} else {
System.out.println("wrong format");
}
}
}
}
// 读入下一个桌号标识
orderLine = scanner.nextLine();
}
scanner.close();
for (Table table : tables) {
if (table.isFlag() && table.getTotalPrice() != 0) {
System.out.println(table.printInfo());
}
}
names.sort(Comparator.naturalOrder());
for (String customerName : names) {
int sum = 0;
String customerPhone = null;
for (Table table : tables) {
if (table.getName().equals(customerName)) {
sum += table.getCheckedPrice();
customerPhone = table.getPhone();
}
}
if (sum != 0) {
System.out.println(customerName + " " + customerPhone + " " + Math.round(sum));
}
}
}
}
enum DishType {
Chuan,
Jin,
Zhe,
}
class Dish {
private final String name;
private final int unitPrice;
private DishType type;
public Dish(String name, int unitPrice, DishType type) {
this.name = name;
this.unitPrice = unitPrice;
this.type = type;
}
public Dish(String name, int unitPrice) {
this.name = name;
this.unitPrice = unitPrice;
}
@Override
public String toString() {
return name;
}
public Object getName() {
return name;
}
public DishType getType() {
return type;
}
public int getUnitPrice() {
return unitPrice;
}
}
class Menu {
private final ArrayList<Dish> dishes = new ArrayList<>();
public Dish searchDish(String dishName) {
for (Dish dish : dishes) {
if (dish.getName().equals(dishName)) {
return dish;
}
}
return null;
}
public void addDish(String dishName, int unitPrice) {
dishes.add(new Dish(dishName, unitPrice));
}
public void addDish(String dishName, int unitPrice, DishType type) {
dishes.add(new Dish(dishName, unitPrice, type));
}
}
class Record {
private final int orderNum;
private final Dish dish;
private final int portion;
private final int quantity;
private final int level;
private final boolean flag;
private final int givenId;
public Record(int givenId, int orderNum, Dish dish, int portion, int quantity) {
this.orderNum = orderNum;
this.dish = dish;
this.portion = portion;
this.quantity = quantity;
this.level = -1;
this.flag = true;
this.givenId = givenId;
}
public Record(int givenId, int orderNum, Dish dish, int level, int portion, int quantity) {
this.orderNum = orderNum;
this.dish = dish;
this.portion = portion;
this.quantity = quantity;
this.level = level;
this.flag = checkLevel();
this.givenId = givenId;
}
private boolean checkLevel() {
switch (dish.getType()) {
case Chuan:
return level <= 5 && level >= 0;
case Jin:
return level <= 4 && level >= 0;
case Zhe:
return level <= 3 && level >= 0;
default:
return true;
}
}
public double getPrice() {
if (!flag)
return 0;
double coefficient = 0;
switch (portion) {
case 1:
coefficient = 1;
break;
case 2:
coefficient = 1.5;
break;
case 3:
coefficient = 2;
break;
}
return Math.round(dish.getUnitPrice() * coefficient) * quantity;
}
public int getCheckedPrice(double coefficient) {
return (int) Math.round(getPrice() * coefficient);
}
public String print(int tableId) {
if (!flag) {
switch (dish.getType()) {
case Chuan:
return "spicy num out of range :" + level;
case Jin:
return "acidity num out of range :" + level;
case Zhe:
return "sweetness num out of range :" + level;
default:
return null;
}
} else {
if (givenId == tableId) {
return orderNum + " " + dish.toString() + " " + Math.round(getPrice());
}
return orderNum + " table " + tableId + " pay for table " + givenId + " " + Math.round(getPrice());
}
}
@Override
public String toString() {
return "Record [orderNum=" + orderNum + ", dish=" + dish + ", portion=" + portion + ", quantity=" + quantity
+ ", level=" + level + ", flag=" + flag + ", givenId=" + givenId + "]";
}
public int getLevel() {
return level;
}
public Dish getDish() {
return dish;
}
public boolean isFlag() {
return flag;
}
public int getGivenId() {
return givenId;
}
public int getQuantity() {
return quantity;
}
public int getOrderNum() {
return orderNum;
}
}
class Table {
private final ArrayList<Record> records = new ArrayList<>();
private final int tableId;
private final String name;
private final String phone;
private final Date date;
private final Date time;
private boolean flag;
public Table(int tableId, String name, String phone, Date date, Date time) {
this.name = name;
this.phone = phone;
this.date = date;
this.time = time;
this.tableId = tableId;
this.flag = true;
}
public double getCoefficient(boolean special) throws ParseException {
double coefficient = 0;
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm");
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
// 营业时间
if (dayOfWeek == 1 || dayOfWeek == 7) {
if (time.after(sdfTime.parse("9:29")) && time.before(sdfTime.parse("21:31"))) {
coefficient = 1;
}
} else {
if (time.after(sdfTime.parse("16:59")) && time.before(sdfTime.parse("20:31"))) {
if (special) {
coefficient = 0.7;
} else {
coefficient = 0.8;
}
} else if (time.after(sdfTime.parse("10:29")) && time.before(sdfTime.parse("14:31"))) {
if (special) {
coefficient = 0.7;
} else {
coefficient = 0.6;
}
}
}
if (coefficient == 0) {
flag = false;
}
return coefficient;
}
public int getTotalPrice() {
int sum = 0;
for (Record record : records) {
sum += (int) record.getPrice();
}
return sum;
}
public int getCheckedPrice() throws ParseException {
int sum = 0;
for (Record record : records) {
if (record.getLevel() != -1) {
sum += record.getCheckedPrice(getCoefficient(true));
} else {
sum += record.getCheckedPrice(getCoefficient(false));
}
}
return sum;
}
public String getAveLevel(DishType type) {
String[] spicy = {"不辣", "微辣", "稍辣", "辣", "很辣", "爆辣"};
String[] acidity = {"不酸", "微酸", "稍酸", "酸", "很酸"};
String[] sweetness = {"不甜", "微甜", "稍甜", "甜"};
double sum = 0;
double num = 0;
for (Record record : records) {
if (record.getDish().getType() == type) {
if (record.isFlag() && tableId == record.getGivenId()) {
num += record.getQuantity();
sum += record.getLevel() * record.getQuantity();
}
}
}
if (num == 0) {
return "";
}
int ave = (int) Math.round(sum / num);
switch (type) {
case Chuan:
return " 川菜 " + (int) num + " " + spicy[ave];
case Jin:
return " 晋菜 " + (int) num + " " + acidity[ave];
case Zhe:
return " 浙菜 " + (int) num + " " + sweetness[ave];
default:
return null;
}
}
public void addRecord(Record record) {
records.add(record);
}
public boolean delRecordByOrderNum(int orderNum) {
return records.removeIf(record -> record.getOrderNum() == orderNum);
}
public String printId() {
return "table " + tableId + ": ";
}
public String printInfo() throws ParseException {
String chuan = getAveLevel(DishType.Chuan);
String jin = getAveLevel(DishType.Jin);
String zhe = getAveLevel(DishType.Zhe);
if (chuan.isEmpty() && jin.isEmpty() && zhe.isEmpty()) {
return "table " + tableId + ": " + getTotalPrice() + " " + getCheckedPrice() + " ";
} else {
StringBuilder sb = new StringBuilder();
sb.append("table ").append(tableId).append(": ").append(getTotalPrice()).append(" ").append(getCheckedPrice());
if (!chuan.isEmpty()) {
sb.append(chuan);
}
if (!jin.isEmpty()) {
sb.append(jin);
}
if (!zhe.isEmpty()) {
sb.append(zhe);
}
return sb.toString();
}
}
public boolean isFlag() {
return flag;
}
public int getTableId() {
return tableId;
}
public Object getName() {
return name;
}
public String getPhone() {
return phone;
}
}


代码如下:
点击查看代码
import java.util.Scanner;
abstract class Shape {
public abstract double getArea();
}
class Circle extends Shape {
private double radius;
Circle(){
}
public Circle(double radius) {
this.radius = radius;
}
public void setRadius(double radius){
this.radius = radius;
}
public double getRadius(){
return this.radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
private Point topLeftPoint;
private Point lowerRightPoint;
Rectangle(Point topLeftPoint, Point lowerRightPoint) {
this.topLeftPoint = topLeftPoint;
this.lowerRightPoint = lowerRightPoint;
}
public Point getTopLeftPoint(){
return this.topLeftPoint;
}
public void setTopLeftPoint(Point topLeftPoint){
this.topLeftPoint = topLeftPoint;
}
public Point getLowerRightPoint(){
return this.lowerRightPoint;
}
public void setLowerRightPoint(Point lowerRightPoint){
this.lowerRightPoint = lowerRightPoint;
}
public double getLength() {
return Math.abs(topLeftPoint.getX() - lowerRightPoint.getX());
}
public double getHeight() {
return Math.abs(topLeftPoint.getY() - lowerRightPoint.getY());
}
public double getArea() {
double length = getLength();
double height = getHeight();
return length * height;
}
}
class Point {
private double x;
private double y;
Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x){
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y){
this.y = y;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
switch (choice) {
case 1: // Circle
double radius = input.nextDouble();
Shape circle = new Circle(radius);
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);
Shape rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
printArea(rectangle);
break;
}
}
public static void printArea(Shape shape) {
double area = shape.getArea();
System.out.printf("%.2f\n", area);
}
}
第四题因为测试点的不同我反而能拿到满分

代码如下:
点击查看代码
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
interface Comparable {
int compareTo(Shape shape);
}
abstract class Shape implements Comparable, java.lang.Comparable<Shape> {
public abstract double getArea();
public int compareTo(Shape shape) {
double area1 = this.getArea();
double area2 = shape.getArea();
if (area1 < area2) {
return -1;
} else if (area1 > area2) {
return 1;
} else {
return 0;
}
}
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
private Point topLeftPoint;
private Point lowerRightPoint;
Rectangle(Point topLeftPoint, Point lowerRightPoint) {
this.topLeftPoint = topLeftPoint;
this.lowerRightPoint = lowerRightPoint;
}
public double getLength() {
return Math.abs(topLeftPoint.getX() - lowerRightPoint.getX());
}
public double getHeight() {
return Math.abs(topLeftPoint.getY() - lowerRightPoint.getY());
}
public double getArea() {
double length = getLength();
double height = getHeight();
return length * height;
}
}
class Point {
private double x;
private double y;
Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ArrayList<Shape> list = new ArrayList<>();
int choice = input.nextInt();
while (choice != 0) {
switch (choice) {
case 1: // Circle
double radius = input.nextDouble();
Shape circle = new Circle(radius);
list.add(circle);
break;
case 2: // Rectangle
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
Point leftTopPoint = new Point(x1, y1);
Point lowerRightPoint = new Point(x2, y2);
Shape rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
list.add(rectangle);
break;
}
choice = input.nextInt();
}
list.sort(Comparator.<Shape>naturalOrder()); // 正向排序
for (int i = 0; i < list.size(); i++) {
System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
}
}
}
踩坑心得
经过这一阶段的学习与实践,我总结出了如下的问题
- 代码结构较为复杂,类的嵌套较多,可读性较差。
- 部分代码重复,可以进行优化和简化。
- 没有使用面向对象的设计原则,如封装、继承、多态等,代码可维护性较差。
改进建议 - 优化代码结构,将每个类的功能和职责分离开来,提高代码的可读性和可维护性。
- 使用面向对象的设计原则,如封装、继承、多态等,提高代码的可维护性和扩展性。
- 优化代码逻辑,避免重复的代码,提高代码的效率和简洁性。
总结
相比于上一阶段的学习,我的能力有了一定的提升,经验也更加丰富了,但还是存在许多不足,比如还是不能在写代码前合理运用类图来完成代码,希望我在下一个阶段的学习中学会应用。

浙公网安备 33010602011771号