BLOG-2
一、 前言
无论是期中考试还是4、5次大作业,题目每题之间都是密不可分的,比如第一题写好的代码你在第二题中可能就要用它作为一个子类。期中考试没有取得好成绩,一方面是因为第一次正式考试,没有实战经验,导致到了考试时间还没有将代码提交上去的情况,少拿了很多分。但是归根到底,这还是我知识不够扎实的原因,如果基础知识足够扎实,无论是什么题目都不应该出现时间不够的问题。而第4、5次作业是在前几次作业上的再次拓展,由菜单3拓展到菜单4,再由菜单3拓展到菜单5,这无疑极大的增加了题目的复杂度,不仅因为之前基础子类体系没有完善好,再加上菜单4的各情况要求判断十分复杂,这都让题目变得十分棘手。但总的来说,题目是老师精心挑选出来的,题量以及难易度肯定是没得说,都在可接受范围内,只要我们认真结合老师点拨与网络资源,这几次作业可以成为我们学习路上典例中的典例,值得不断探索学习。
二、 设计与分析
7-3 判断两个日期的先后,计算间隔天数、周数
从键盘输入两个日期,格式如:2022-06-18。判断两个日期的先后,并输出它们之间间隔的天数、周数(不足一周按0计算)。
预备知识:通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。
输入格式:
输入两行,每行输入一个日期,日期格式如:2022-06-18
输出格式:
第一行输出:第一个日期比第二个日期更早(晚)
第二行输出:两个日期间隔XX天
第三行输出:两个日期间隔XX周
输入样例1:
2000-02-18
2000-03-15
输出样例1:
第一个日期比第二个日期更早
两个日期间隔26天
两个日期间隔3周
输入样例2:
2022-6-18
2022-6-1
输出样例2:
第一个日期比第二个日期更晚
两个日期间隔17天
两个日期间隔2周
1 import java.text.DateFormat;
2 import java.text.SimpleDateFormat;
3 import java.time.LocalDate;
4 import java.time.Year;
5 import java.time.LocalDate;
6 import java.time.temporal.ChronoUnit;
7 import java.util.Scanner;
8 import java.time.format.DateTimeFormatter;
9 public class Main {
10 public static void main(String[] args) {
11 Scanner input = new Scanner(System.in);
12 String line = input.nextLine() ;
13 String line2 = input.nextLine() ;
14 String[] arr1 = line.split("-");
15 int year1 = Integer.parseInt(arr1[0]) ;
16 int month1 = Integer.parseInt(arr1[1]) ;
17 int day1 = Integer.parseInt(arr1[2]) ;
18 String[] arr2 = line2.split("-") ;
19 int year2 = Integer.parseInt(arr2[0]) ;
20 int month2 = Integer.parseInt(arr2[1]) ;
21 int day2 = Integer.parseInt(arr2[2]) ;
22 LocalDate cal1 = LocalDate.of(year1,month1,day1) ;
23 LocalDate cal2 = LocalDate.of(year2,month2,day2) ;
24 long day3 = ChronoUnit.DAYS.between(cal1,cal2);
25 if(day3<0)
26 {
27 System.out.println("第一个日期比第二个日期更晚") ;
28 day3=-day3;
29 }
30 else
31 System.out.println("第一个日期比第二个日期更早") ;
32 System.out.println("两个日期间隔"+day3+"天") ;
33 System.out.println("两个日期间隔"+(int)day3/7+"周") ;
34
35 }
代码类图:
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"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.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
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;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}
}
class Menu {
Dish[] dishs = new Dish[30];//菜品数组,保存所有菜品信息
int count = 0;
Dish searthDish(String dishName){
Dish temd = null;
for(int i=count-1;i>=0;i--)
{
if(dishName.equals(dishs[i].name)){
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++;
return dh;
}//添加一道菜品信息
}
class Record {
int orderNum;//序号\
Dish d = new Dish();//菜品\
int num = 0;
int portion;//份额(1/2/3代表小/中/大份)\
//int exist = 1;
int getPrice(){
return d.getPrice(portion)*num;
}//计价,计算本条记录的价格\
}
class Order {
Record[] records = new Record[30];//保存订单上每一道的记录
int count = 0;//订单数量
void addARecord(int orderNum,String dishName,int portion,int num){
records[count] = new Record();
records[count].d.name = dishName;
records[count].orderNum = orderNum;
records[count].portion = portion;
records[count].num = num;
}//添加一条菜品信息到订单中。
int delARecordByOrderNum(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 week,hh,mm,ss;
int sum = 0;//一桌价格 ;
Order odt = new Order();
float discnt = -1;
void Gettottalprice(){
if(discnt>0){
sum = Math.round(sum*discnt);
System.out.println("table " + tableNum + ": " + sum);
}else {
System.out.println("table " + tableNum + " out of opening hours");
}
}
void AheadProcess(String tableDtime){
this.tableDtime = tableDtime;
processTime();
discount();
}
void processTime(){//处理时间
String[] temp = tableDtime.split(" ");
tableNum = Integer.parseInt(temp[1]);
String[] temp2 = temp[3].split("/");
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy/M/d");
LocalDate date = LocalDate.parse(temp[2], formatter1); // 将字符串解析为LocalDate对象
DayOfWeek dayOfWeek = date.getDayOfWeek();
if(dayOfWeek ==DayOfWeek.WEDNESDAY )
week = 3;
else if(dayOfWeek ==DayOfWeek.MONDAY)
week= 1;
else if(dayOfWeek ==DayOfWeek.TUESDAY)
week = 2;
else if(dayOfWeek ==DayOfWeek.THURSDAY)
week = 4;
else if(dayOfWeek ==DayOfWeek.FRIDAY)
week = 5;
else if(dayOfWeek ==DayOfWeek.SATURDAY)
week = 6;
else if(dayOfWeek ==DayOfWeek.SUNDAY)
week = 7;
hh = Integer.parseInt(temp2[0]);
mm = Integer.parseInt(temp2[1]);
ss = Integer.parseInt(temp2[2]);
}
void discount(){
int timeu= hh * 10000 + mm * 100 + ss;
if(week>=1 && week<=5)
{
if(timeu >= 170000 && timeu <= 203000)
discnt = 0.8F;
else if(timeu >= 103000 && timeu <= 143000)
discnt = 0.6F;
}
else
{
if(timeu >= 93000 && timeu <= 213000)
discnt = 1.0F;
}
}
}
public class Main {
public static void main(String[] args) {
String price = "([1-9]?[0-9]|100)";
String Type = "(delete)";
String tbl ="(table)";
String name = "\\S{1,10}";//1到10个非空格(TAB)字符
String date = "(\\d{4}/\\d{1,2}/\\d{1,2})";
String time ="(\\d{1,2}/\\d{1,2}/\\d{1,2})";
/* String ordeInput = price + " " + name + " " + price + " "+price;
String meuninput = name +" "+ price;
String delinput = price +" "+ Type;
String table = tbl +" "+ price+" "+date+" "+time;
String dai = price + " " + price +" "+name+" "+price+" "+price;*/
Scanner sc = new Scanner(System.in);
Menu mu = new Menu();
//inputin mat = new inputin() ;
Table[] tablemes = new Table[30];
int j = 0;//菜单数
int l = 0;//订单数
int k = 0;//代点菜数
Dish tt;
int cntTable = 0;//桌号
int count;
String[] temp;
int a1,a2,a3,a4,a5,k1=0;
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")) {//第二个为delete
a1 = Integer.parseInt(temp[0]);
int c = tablemes[cntTable].odt.delARecordByOrderNum(a1);
tablemes[cntTable].sum -= c;
} else {//菜单添加
a2 = Integer.parseInt(temp[1]);
mu.dishs[j] = mu.addDish(temp[0], a2);
j++;
mu.count = j;
}
}
else if (count == 4) {//三个空格
if (temp[0].equals("table")) {//桌号
cntTable++;//跳过0;
tablemes[cntTable] = new Table();
tablemes[cntTable].AheadProcess(st);
System.out.println("table " + cntTable + ": ");
} else {//增加订单的情况;
if(cntTable != k1){
l= 0;
k1 = cntTable ;
tablemes[cntTable].odt.count = l;
}
a3 =Integer.parseInt(temp[0]);
a4 = Integer.parseInt(temp[2]);
a5=Integer.parseInt(temp[3]);
tablemes[cntTable].odt.addARecord(a3, temp[1],a4 , a5);
tt = mu.searthDish(temp[1]);
if (tt != null) {
tablemes[cntTable].odt.records[l].d = tt;
int a = tablemes[cntTable].odt.records[l].getPrice();
System.out.println(tablemes[cntTable].odt.records[l].orderNum + " " + tt.name + " " +a );
tablemes[cntTable].sum += a;
}
l++;
tablemes[cntTable].odt.count = l;
}
}
else if (count == 5) {//代点菜
a1 = Integer.parseInt(temp[1]);
a2 = Integer.parseInt(temp[3]);
a3 = Integer.parseInt(temp[4]);
tablemes[cntTable].odt.addARecord( a1, temp[2], a2, a3);
tt = mu.searthDish(temp[2]);
if (tt != null) {
tablemes[cntTable].odt.records[l].d.unit_price = tt.unit_price;
int b = tablemes[cntTable].odt.records[l].getPrice();
System.out.println(temp[1] + " table " + tablemes[cntTable].tableNum + " pay for table " + temp[0] + " " + b);
tablemes[cntTable].sum += b;
}
l++;
tablemes[cntTable].odt.count = l;
}
}
for (int i = 1; i < cntTable + 1; i++) {
tablemes[i].Gettottalprice();
}
}
}
class inputin{
static String price = "([1-9]?[0-9]|100)";
static String Type = "(delete)";
static String tbl ="(table)";
static String name = "\\S{1,10}";//1到10个非空格(TAB)字符
static String date = "(\\d{4}/\\d{1,2}/\\d{1,2})";
static String time ="(\\d{1,2}/\\d{1,2}/\\d{1,2})";
static String ordeInput = price + " " + name + " " + price + " "+price;
static String meuninput = name +" "+ price;
static String delinput = price +" "+ Type;
static String table = tbl +" "+ price+" "+date+" "+time;
static String dai = price + " " + price +" "+name+" "+price+" "+price;
public int matchingInput(String s) {
if (s.matches(ordeInput) )
return 1;
if (s.matches(meuninput))
return 2;
if(s.matches(delinput))
return 0;
if(s.matches(table))
return 3;
if(s.matches(dai) )
return 4;
return -1;
}
}
类图如下:
在执行这段代码时会运行超时,多次提交后过了,经过我多次的验证后发现是我创建的那个类,类的new和调用都会消耗时间,而且在新创建的类的代码越复杂消耗的时间就越多。
本体大部分内容与菜单计价程序-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
其他用例请参考公开的测试用例
1 import java.time.LocalDate;
2 import java.time.LocalDateTime;
3 import java.util.Scanner;
4 public class Main{
5 public static void main(String[] args){
6 int j=0,flag=1,i=-1,k=0,m=0,n=0,p=0,q=0,flag3=0;
7 Scanner input=new Scanner(System.in);
8 Table[] tables=new Table[30];
9 Menu menu=new Menu();
10 //Rt rt=new Rt();
11 String p1 = "([1-9]|[1-9][0-9]+)";
12 String p2 = "[\u4E00-\u9FA5]+";
13 String p3 = "[0-9]";
14 String p4 = "([1-9][0-9]?|[1-2][0-9]{2})";
15 String p5 = "table[ ]([1-9]|[1-9][0-9]+)[ ][0-9]{4}";
16 String p6 = "\\/([0-9]|[0-9]{2})";
17 String p7 = "\\/([0-9]|[0-9]{2})[ ]([0-9]|[0-9]{2})" ;
18 String p8 = "([0-9]|[0-1][0-9]|20|21|22|23)";
19 String p9 = "[/]([0-5][0-9])";
20 String tabl1 = p5+ p6+p7+p6+p6;
21 String date1 = "^((\\d{2}(([02468][048])|([13579][26]))" +
22 "[\\-\\/\\s]?((((0?[13578])|(1[02]))" +
23 "[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))" +
24 "[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))" +
25 "[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))" +
26 "[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))";
27 String time5 = p8+p9+p9;
28 String delete1 = p1+" "+"delete";
29 String order3 = p1+" "+ p2+" "+p3+" "+p1;
30 String order2 = p1+" "+order3;
31 String table2 = "[1-9]|[1-4][0-9]|5[0-5]";
32 String menu1 = p2+" "+p1;
33 String t = "T";
34 String menu2 = menu1+" "+t;
35 String menu3 = p2+" "+p4;
36 String menu4 = menu3+" "+t ;
37 String gh2 = "[1-3]";
38 String gh3 = "[1-9]|1[0-5]";
39 String tabl2 = "t(.*)";
40 String tabl3 = "table(.*)";
41 Panduan panduan=new Panduan();
42 while(true) {
43 String s = input.nextLine();
44 if (s.equals("end"))
45 break;
46 if (s.matches(tabl2 )) {
47 if(s.matches(tabl3 )) {
48 if(s.matches(tabl1))
49 {
50 String[] te=s.split(" |\\/");
51 String shijian=te[5]+"/"+te[6]+"/"+te[7];
52 LocalDate localDate1=LocalDate.of(2022,1,1);
53 LocalDate localDate2=LocalDate.of(2023,12,31);
54 String riqi=te[2]+"-"+te[3]+"-"+te[4];
55
56 if(!(te[1].matches(table2))){
57 flag=0;
58 System.out.println(te[1]+" table num out of range");
59 } else if (!(riqi.matches(date1))||!shijian.matches(time5)) {
60 flag=0;
61 System.out.println(te[1]+" date error");
62 }else{
63 int kn = Integer.parseInt(te[2]);
64 int kn1 = Integer.parseInt(te[3]);
65 int kn2 = Integer.parseInt(te[4]);
66 int kn3 = Integer.parseInt(te[5]);
67 int kn4 = Integer.parseInt(te[6]);
68 int kn5 = Integer.parseInt(te[7]);
69 LocalDate localDate=LocalDate.of(kn, kn1,kn2 );
70 LocalDateTime localDateTime=LocalDateTime.of(kn, kn1, kn2,kn3 , kn4, kn5 );
71 if (panduan.panduan2(localDateTime)==0) {
72 System.out.println("table " + te[1] + " out of opening hours");
73 flag=0;
74 }
75 else if(localDate.isBefore(localDate1)||localDate.isAfter(localDate2)){
76 System.out.println("not a valid time period");
77 flag=0;} else{
78 i++;
79 int km =Integer.parseInt(te[1]);
80 tables[i] = new Table();
81 tables[i].tablenum = km;
82 tables[i].localDateTime=localDateTime;
83 flag=1;
84 System.out.println("table"+' '+te[1]+": ");
85 }
86 }
87 }
88 else{
89 System.out.println("wrong format");
90 flag=0;
91 }
92 }
93 else{
94 System.out.println("wrong format");}
95 //这里进行i不加对上一个桌的继承。
96 } else {
97 if (flag == 1) {
98 if (s.matches(delete1)) {
99 String[] dd = s.split(" ");
100 int ke = Integer.parseInt(dd[0]);
101 if ((tables[i].findRecordByNum(tables[i], ke, tables[i].i) != 1) && (tables[i].findRecorddByNum(tables[i], ke, tables[i].j) != 1))
102 System.out.println("delete error;");
103 } else if (s.matches(order2 )) {
104 String[] dd = s.split(" ");
105 flag3=0;
106 int ky = Integer.parseInt(dd[0]);
107 for (j = 0; j <= i; j++) {//判断自己给自己点菜
108 if (tables[j].tablenum == ky ){
109 flag3=1;
110 break;}
111 }
112 if(flag3==1){
113 if (menu.searthDish(dd[2]) == null)
114 System.out.println(dd[2] + " " + "does not exist");
115 else if(tables[j].tablenum==tables[i].tablenum){
116 System.out.println("Table number :" + dd[0] + " does not exist");
117 }
118 else{
119 int ky1 = Integer.parseInt(dd[1]);
120 int ky2 = Integer.parseInt(dd[3]);
121 int ky3 = Integer.parseInt(dd[4]);
122 int ky4 = tables[i].j;
123 tables[i].recordsd[ky4] = tables[i].addaRecordd(menu, ky, ky1, dd[2], ky2,ky3 );
124 System.out.println(tables[i].recordsd[ky4].orderNum + " table " + tables[i].tablenum + " pay for table " + dd[0] + " " + tables[i].recordsd[ky4].getPrice);
125 tables[i].j++;
126 }
127 } else
128 System.out.println("Table number :" + dd[0] + " does not exist");
129 }
130 else if (s.matches(order3 )) {
131 String[] bz = s.split(" ");
132 int kj = Integer.parseInt(bz[0]);
133 int kj5 = tables[i].i;
134 if (kj5!=0){
135 if(kj <= tables[i].records[kj5-1].orderNum){
136 System.out.println("record serial number sequence error");
137 continue;}
138 }
139 if (menu.searthDish(bz[1])== null)
140 System.out.println(bz[1] + " " + "does not exist");
141 else if (!bz[2].matches(gh2) && menu.searthDish(bz[1]).flag == 0) {
142 System.out.println(bz[0] + " portion out of range " + bz[2]);
143 }else if (!bz[3].matches(gh3)) {
144 System.out.println(bz[0] + " num out of range " + bz[3]);
145 }
146 else if (!bz[2].matches(gh2) && menu.searthDish(bz[1]).flag == 1)
147 System.out.println(bz[0] + " portion out of range " + bz[2]);
148 else{
149 int kj1 = Integer.parseInt(bz[2]);
150 int kj2 = Integer.parseInt(bz[3]);
151 tables[i].records[tables[i].i] = tables[i].addaRecord(menu, kj, bz[1],kj1 , kj2);
152 System.out.println(bz[0] + " " + bz[1] + " " + tables[i].records[tables[i].i].getPrice);
153 tables[i].i++;}
154 }
155 else if (s.matches(menu1) || s.matches(menu2)) {//进入菜单
156 if (i == -1) {
157 int flag1 = 0, flag2 = 1;
158 boolean cheak1 = s.matches(menu1 );
159 boolean cheak2 = s.matches(menu2 );
160 String[] tokens = s.split(" ");
161 int kl = Integer.parseInt(tokens[1]);
162 if (cheak2) {
163 if (s.matches(menu4)) {
164 menu.addDish(tokens[0], kl, flag2);
165 menu.f ++;
166 }
167 else
168 System.out.println(tokens[0] + " price out of range " + tokens[1]);
169 }
170 if (cheak1) {
171 if (s.matches(menu3)) {
172 menu.addDish(tokens[0], kl, flag1);
173 menu.f ++;
174 }
175 else
176 System.out.println(tokens[0] + " price out of range " + tokens[1]);
177 }
178 } else
179 System.out.println("invalid dish");
180 } else {
181 System.out.println("wrong format");
182 }
183 }
184 }
185 }
186 for(j=0;j<=i;j++) {
187 if(tables[j].flag==1){
188 for(k=j+1;k<=i;k++) {
189 if(tables[k].tablenum==tables[j].tablenum){
190 if(panduan.panduan( tables[k].localDateTime, tables[j].localDateTime)!=0||panduan.panduan1( tables[k].localDateTime, tables[j].localDateTime)!=0){
191 tables[k].flag=0;
192 for(m=0;m< tables[j].i;m++){
193 if( tables[j].records[m].flag==1){
194 for(n=m+1;n< tables[j].i;n++){
195 if( tables[j].records[n].portion== tables[j].records[m].portion&& tables[j].records[n].d.name== tables[j].records[m].d.name){
196 tables[j].records[n].flag=0;
197 tables[j].records[m].num+= tables[j].records[n].num;
198 }
199 }
200 }
201 for (p=0; p< tables[k].i; p++) {
202 if ( tables[k].records[p].portion == tables[j].records[m].portion && tables[k].records[p].d.name == tables[j].records[m].d.name) {
203 tables[k].records[p].flag = 0;
204 tables[j].records[m].num += tables[k].records[p].num;
205 }
206 }
207 }
208 }//if
209 }
210 else{
211 for(m=0;m< tables[j].i;m++){
212 if( tables[j].records[m].flag==1){
213 for(n=m+1;n< tables[j].i;n++){
214 if( tables[j].records[n].portion== tables[j].records[m].portion&& tables[j].records[n].d.name== tables[j].records[m].d.name){
215 tables[j].records[m].num+= tables[j].records[n].num;
216 tables[j].records[n].flag=0;
217 }
218 }
219 }
220 for (p=0; p< tables[j].j; p++) {
221 if ( tables[j].recordsd[p].portion == tables[j].records[m].portion && tables[j].records[p].d.name == tables[j].records[m].d.name) {
222 tables[j].records[m].num += tables[j].recordsd[p].num;
223 tables[j].recordsd[p].flag = 0;
224 }
225 }
226 }
227 }
228 }
229 }
230 }
231 for(j=0;j<=i;j++){
232 for(k=0;k< tables[j].j;k++)
233 tables[j].TotalPrice += tables[j].recordsd[k].d.getPrice( tables[j].recordsd[k].portion)* tables[j].recordsd[k].num;
234 for(k=0;k< tables[j].i;k++)
235 tables[j].TotalPrice += tables[j].records[k].d.getPrice( tables[j].records[k].portion)* tables[j].records[k].num;
236 for(k=0;k< tables[j].j;k++)
237 tables[j].TotalPricez+=panduan.jisuan( tables[j], tables[j].recordsd[k]);
238 for(k=0;k< tables[j].i;k++)
239 tables[j].TotalPricez+=panduan.jisuan( tables[j], tables[j].records[k]);
240
241 if( tables[j].flag==1)
242 System.out.println("table"+" "+ tables[j].tablenum+": "+ tables[j].TotalPrice+" "+ tables[j].TotalPricez);
243 }
244 }
245 }
246 class Dish {
247 String name;
248 int unit_price;
249 public Dish(String name,int unit_price){
250 this.unit_price = unit_price;
251 this.name = name;
252 }
253 int flag=0