JAVA PTA1~3题目集总结
一、前言:
第一次题目集主要让我熟悉使用Java语法,题目比较简单,用C语言的逻辑和Java语法全部完成了。题量适中,难度适中。
第二次题目集开始很难,出现了两份菜单设计和jmu-java-日期类的基本使用。努力努力学习别人的代码,成功写出来了。题量一般,有点难度。
第三次题目集开始很很难,出现了升级版菜单设计和一堆更难的题目。努力努力也写不出菜单,别的题目写出来了。题量偏大,菜单难度极大,其余题目难度偏大。
二、题目分析
某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9
设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)
不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格2。
如果计算出现小数,按四舍五入的规则进行处理。
参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}
菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}
点菜记录类:保存订单上的一道菜品记录
Record {
Dish d;//菜品
int portion;//份额(1/2/3代表小/中/大份)
int getPrice()//计价,计算本条记录的价格
}
订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(String dishName,int portion)
//添加一条菜品信息到订单中。
}
输入格式:
每条点菜记录的格式:
菜名+空格(英文)+份额
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
最后一条记录以“end”结束。
输出格式:
订单上所有菜品的总价(整数数值),每份菜
如果订单中包含不能识别的菜名,则在总价之前输出“** does not exist”,**是不能识别的菜名
输入样例:
在这里给出一组输入。例如:
麻婆豆腐 2
西红柿炒蛋 3
end
输出样例:
在这里给出相应的输出。例如:
48
输入样例1:
订单中包含不存在的菜品记录。例如:
麻婆豆腐 2
炒脆肚 2
西红柿炒蛋 3
end
输出样例1:
在这里给出相应的输出。例如:
炒脆肚 does not exist
48
-
类的设计与实现:需要设计并实现
Dish、Menu、Record和Order这几个类来表示菜品、菜谱、点菜记录和订单。 -
字符串操作:涉及菜品名称的存储、比较和解析。
-
数组操作:在菜谱和订单中使用数组来保存多个菜品或点菜记录。
-
循环和条件语句:用于在菜谱中查找菜品信息和计算订单总价。
-
方法设计:每个类需要设计相应的方法来实现特定的功能,如计算菜品价格、查找菜品、计算点菜记录价格等。
-
对象关联:类之间可能存在关联关系,如
Order类中需要使用Menu类的方法来获取菜品信息。 -
异常处理:需要处理无法识别的菜名,并显示错误信息。
-
小数处理:根据要求,需要对价格进行四舍五入处理,可以使用
Math.round()方法。
import java.util.*; import java.util.Scanner; // 菜品类 class Dish { String name; // 菜品名称 int unit_price; // 单价 // 构造函数 Dish(String name, int unit_price) { this.name = name; this.unit_price = unit_price; } // 计算菜品价格的方法 int getPrice(int portion) { double price = unit_price; if (portion == 2) { price *= 1.5; } else if (portion == 3) { price *= 2; } return (int) Math.round(price); } } // 菜谱类 class Menu { Dish[] dishes; // 菜品数组,保存所有菜品信息 // 构造函数 Menu(Dish[] dishes) { this.dishes = dishes; } // 根据菜名在菜谱中查找菜品信息 Dish searchDish(String dishName) { for (Dish dish : dishes) { if (dish.name.equals(dishName)) { return dish; } } return null; } } // 点菜记录类 class Record { Dish dish; // 菜品 int portion; // 份额(1/2/3代表小/中/大份) // 构造函数 Record(Dish dish, int portion) { this.dish = dish; this.portion = portion; } // 计价,计算本条记录的价格 int getPrice() { return dish.getPrice(portion); } } // 订单类 class Order { List<Record> records; // 保存订单上每一道的记录 // 构造函数 Order() { this.records = new ArrayList<>(); } // 添加一条菜品信息到订 Record addARecord(String dishName, int portion, Menu menu) { Dish dish = menu.searchDish(dishName); if (dish == null) { System.out.println(dishName + " does not exist"); return null; } Record record = new Record(dish, portion); records.add(record); return record; } // 计算订单的总价 int getTotalPrice() { int totalPrice = 0; for (Record record : records) { totalPrice += record.getPrice(); } return totalPrice; } } // 主函数 public class Main { public static void main(String[] args) { // 创建菜谱 Dish[] dishes = { new Dish("西红柿炒蛋", 15), new Dish("清炒土豆丝", 12), new Dish("麻婆豆腐", 12), new Dish("油淋生菜", 9) }; Menu menu = new Menu(dishes); // 创建订单 Order order = new Order(); // 读取点菜记录 Scanner scanner = new Scanner(System.in); while (true) { String line = scanner.nextLine(); if (line.equals("end")) { break; } String[] parts = line.split(" "); String dishName = parts[0]; int portion = Integer.parseInt(parts[1]); order.addARecord(dishName, portion, menu); } // 输出总价 System.out.println(order.getTotalPrice()); } }
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"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.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Menu menu = new Menu();
Order order = new Order(menu);
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
while (!line.equals("end")) {
String[] lineArray = line.split(" ");
if (lineArray.length > 2) {
int orderNum = Integer.parseInt(lineArray[0]);
String dishName = lineArray[1];
int portion = Integer.parseInt(lineArray[2]);
int num = Integer.parseInt(lineArray[3]);
order.addARecord(orderNum, dishName, portion, num);
} else if ("delete".equals(lineArray[1])) {
order.delARecordByOrderNum(Integer.parseInt(lineArray[0]));
} else {
menu.addDish(lineArray[0], Integer.parseInt(lineArray[1]));
}
line = scanner.nextLine();
}
System.out.println(order.getTotalPrice());
}
}
class Menu {
private List<Dish> dishs = new ArrayList<>();//菜品数组,保存所有菜品信息
void addDish(Dish dish) {
}
Menu() {
}
Dish searthDish(String dishName) {
for (Dish dish : dishs) {
if (dish.getName().equals(dishName)) {
return dish;
}
}
return null;
}
//添加一道菜品信息
Dish addDish(String dishName, int unit_price) {
for (Dish dish : dishs) {
if (dish.getName().equals(dishName)) {
dish.setUnit_price(unit_price);
return dish;
}
}
Dish dish = new Dish(dishName, unit_price);
dishs.add(dish);
return dish;
}
}
class Dish {
String name;//菜品名称
int unit_price; //单价
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getUnit_price() {
return unit_price;
}
public void setUnit_price(int unit_price) {
this.unit_price = unit_price;
}
public Dish(String name, int unit_price) {
this.name = name;
this.unit_price = unit_price;
}
public Dish() {
}
//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
int getPrice(int portion) {
float b[] = {1, 1.5f, 2};
return Math.round((unit_price * b[portion - 1]));
}
}
class Record {
private int orderNum;//序号\
private Dish d;//菜品\
private int portion;//份额(1/2/3代表小/中/大份)\
private int num;
private boolean isDelete = false;
public boolean isNotFound() {
return notFound;
}
public void setNotFound(boolean notFound) {
this.notFound = notFound;
}
private boolean notFound = false;
public Record(Dish d, int portion) {
this.d = d;
this.portion = portion;
}
public Record(int orderNum, Dish d, int portion, int num) {
this.orderNum = orderNum;
this.d = d;
this.portion = portion;
this.num = num;
}
//计价,计算本条记录的价格
int getPrice() {
return d.getPrice(portion) * this.num;
}
public int getOrderNum() {
return orderNum;
}
public void setOrderNum(int orderNum) {
this.orderNum = orderNum;
}
public Dish getD() {
return d;
}
public void setD(Dish d) {
this.d = d;
}
public int getPortion() {
return portion;
}
public void setPortion(int portion) {
this.portion = portion;
}
public boolean isDelete() {
return isDelete;
}
public void setDelete(boolean delete) {
isDelete = delete;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
class Order {
private Menu menu;
private static List<Record> records = new ArrayList<>();//保存订单上每一道的记录
public Order(Menu menu) {
this.menu = menu;
}
//计算订单的总价
int getTotalPrice() {
int sum = 0;
for (Record record : records) {
int price = record.getPrice();
if (!record.isDelete()) {
sum = sum + price;
}
}
return sum;
}
//添加一条菜品信息到订单中。
Record addARecord(int orderNum, String dishName, int portion, int num) {
Dish dish = menu.searthDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
return null;
}
Record record = new Record(orderNum, dish, portion, num);
records.add(record);
int price = record.getPrice();
System.out.println(record.getOrderNum() + " " + record.getD().getName() + " " + price);
return record;
}
public boolean delARecordByOrderNum(int orderNum) {
for (Record record : records) {
if (!record.isNotFound() && !record.isDelete() && record.getOrderNum() == orderNum) {
record.setDelete(true);
return true;
}
}
System.out.println("delete error;");
return false;
}
}
菜单2相比菜单1多了删除功能。我通过给每条订单一个布尔型isdelete,通过修改、查询isdelete的真假来判断订单是否被删除,以实现订单的删除功能。
所使用的知识点:
1. 类的设计与实现:需要实现 `Dish`、`Menu`、`Record` 和 `Order` 这几个类来表示菜品、菜谱、点菜记录和订单。
2. 字符串操作:包括菜名和删除指令的解析。
3. 数组操作:用于保存菜谱中的菜品和订单中的点菜记录。
4. 循环和条件语句:用于读取输入、处理订单和菜单。
5. 异常处理:处理无法识别的菜名和删除指令序号不存在的情况。
6. 方法设计:每个类需要设计相应的方法来实现特定的功能,如计算菜品价格、查找菜品、计算点菜记录价格、添加菜品到订单、删除订单中的记录等。
7. 小数处理:计算菜品价格时,需要进行四舍五入处理,可以使用 `Math.round()` 方法。
8. 订单的处理:根据输入的点菜记录和删除指令,对订单进行增加记录、删除记录和计算总价的操作。
9. 输出格式:按照要求输出每条点菜记录的处理信息,包括序号、菜名和价格;如果有不能识别的菜名则输出错误信息;最后输出订单的总价。
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"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
与前者不同的地方:
1. 输入格式增加了桌号标识,每个订单记录前会有桌号标识来指示该记录属于哪一桌的订单。
2. 每个桌号标识后面的所有记录都属于同一桌的订单,直到下一个桌号标识出现。
3. 新增了代点菜信息,用于一个桌号在当前桌为另一桌点菜,而价格计算仍在当前桌进行。
4. 输出格式中添加了桌号标识,输出每一桌的订单记录处理信息。
5. 每一桌的总价计算方法不再仅仅是当前桌上所有菜品价格之和,而是乘以一个折扣系数,并按照四舍五入规则保留整数部分。
6. 折扣系数根据不同的营业时间和日期进行计算,包括周一至周五晚上、周一至周五中午、周末全价等情况。
7. 需要注意处理订单时间是否在营业时间范围内的情况,如果不在范围内则输出相应的提示信息。
8. 在菜品类和订单类中需要增加处理代点菜的逻辑和方法。
需要注意的易错点包括:
1. 正确解析输入的桌号标识,并将点菜记录和代点菜信息与相应的桌号关联起来。
2. 在计算每道菜品价格时,要考虑不同份额的折扣计算和四舍五入规则的处理。
3. 在输出订单记录和总价时,确保按照输入的顺序输出,并正确格式化输出信息。
4. 注意处理代点菜信息时的价格计算和桌号关联。
5. 在计算总价时,要根据不同的日期和营业时间段确定折扣系数,并进行四舍五入处理。
餐单3更加复杂,增添了桌号、代点菜,还需要根据点单时间判断是否在营业时间并计算折扣。我能力水平有限,没能成功运行代码。越修改,error越多。
以下是我的提交代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
Menu menu = new Menu();
Order order = new Order(menu);
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
while (!line.equals("end")) {
String[] lineArray = line.split(" ");
if (lineArray.length > 3) //记录/更改桌号
{
int tablenum=Integer.parseInt(lineArray[0]);
LocalDate date = LocalDate.parse(lineArray[2], DateTimeFormatter.ofPattern("yyyy-M-d"));
LocalDate time = LocalDate.parse(lineArray[3], DateTimeFormatter.ofPattern("yyyy-M-d"));
table.setTable()
}
else if (lineArray.length > 2) {
int orderNum = Integer.parseInt(lineArray[0]);
String dishName = lineArray[1];
int portion = Integer.parseInt(lineArray[2]);
int num = Integer.parseInt(lineArray[3]);
order.addARecord(orderNum, dishName, portion, num);
}
else if ("delete".equals(lineArray[1])) {
order.delARecordByOrderNum(Integer.parseInt(lineArray[0]));
}
else //录入菜单
{
menu.addDish(lineArray[0], Integer.parseInt(lineArray[1]));
}
line = scanner.nextLine();
}
System.out.println(order.getTotalPrice());
}
}
class Menu {
private List<Dish> dishs = new ArrayList<>();//菜品数组,保存所有菜品信息
void addDish(Dish dish) {
}
Menu() {
}
Dish searthDish(String dishName) {
for (Dish dish : dishs) {
if (dish.getName().equals(dishName)) {
return dish;
}
}
return null;
}
//添加一道菜品信息
Dish addDish(String dishName, int unit_price) {
for (Dish dish : dishs) {
if (dish.getName().equals(dishName)) {
dish.setUnit_price(unit_price);
return dish;
}
}
Dish dish = new Dish(dishName, unit_price);
dishs.add(dish);
return dish;
}
}
class Dish {
String name;//菜品名称
int unit_price; //单价
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getUnit_price() {
return unit_price;
}
public void setUnit_price(int unit_price) {
this.unit_price = unit_price;
}
public Dish(String name, int unit_price) {
this.name = name;
this.unit_price = unit_price;
}
public Dish() {
}
//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
int getPrice(int portion) {
float b[] = {1, 1.5f, 2};
return Math.round((unit_price * b[portion - 1]));
}
}
class Record {
private int orderNum;//序号\
private Dish d;//菜品\
private int portion;//份额(1/2/3代表小/中/大份)\
private int num;
private boolean isDelete = false;
public boolean isNotFound() {
return notFound;
}
public void setNotFound(boolean notFound) {
this.notFound = notFound;
}
private boolean notFound = false;
// public Record(Dish d, int portion) {
// this.d = d;
// this.portion = portion;
// }
public Record(int orderNum, Dish d, int portion, int num) {
this.orderNum = orderNum;
this.d = d;
this.portion = portion;
this.num = num;
}
void printRecord(Record record)
{
for (Record record : records) {
int price = record.getPrice();
if (!record.isDelete()) {
System.out.println(record.getOrderNum()+" "+record.getD().getName()+" "+record.getPrice);
}
}
}
//计价,计算本条记录的价格
int getPrice() {
return d.getPrice(portion) * this.num;
}
public int getOrderNum() {
return orderNum;
}
public void setOrderNum(int orderNum) {
this.orderNum = orderNum;
}
public Dish getD() {
return d;
}
public void setD(Dish d) {
this.d = d;
}
public int getPortion() {
return portion;
}
public void setPortion(int portion) {
this.portion = portion;
}
public boolean isDelete() {
return isDelete;
}
public void setDelete(boolean delete) {
isDelete = delete;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
class Order {
private Menu menu;
private static List<Record> records = new ArrayList<>();//保存订单上每一道的记录
public Order(Menu menu) {
this.menu = menu;
}
//计算订单的总价
int getTotalPrice() {
int sum = 0;
for (Record record : records) {
int price = record.getPrice();
if (!record.isDelete()) {
sum = sum + price;
}
}
return sum;
}
//添加一条菜品信息到订单中。
Record addARecord(int orderNum, String dishName, int portion, int num) {
Dish dish = menu.searthDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
return null;
}
Record record = new Record(orderNum, dish, portion, num);
records.add(record);
int price = record.getPrice();
System.out.println(record.getOrderNum() + " " + record.getD().getName() + " " + price);
return record;
}
public boolean delARecordByOrderNum(int orderNum) {
for (Record record : records) {
if (!record.isNotFound() && !record.isDelete() && record.getOrderNum() == orderNum) {
record.setDelete(true);
return true;
}
}
System.out.println("delete error;");
return false;
}
}
class Table{
private Record record;
private int tablenum;
private LocalDate date;
private LocalDate time;
public Table(int tablenum,LocalDate date,LocalDate time) {
this.record=record;
this.tablenum = tablenum;
this.date = date;
this.time=time;
}
public void setTable(int tablenum,LocalDate date,LocalDate time)
{
this.tablenum=tablenum;
this.date=date;
this.time=time;
}
public void setTable2(Record record)
this.record=record;
}
三、遇到的困难与问题
- 给定一个日期,判定是否为合法日期。如果合法,判断该年是否闰年,该日期是当年第几天、当月第几天、当周第几天、。
- 给定起始日期与结束日期,判定日期是否合法且结束日期是否早于起始日期。如果均合法,输出结束日期与起始日期之间的相差的天数、月数、念书。
Scanner类从键盘读取用户输入的两个日期,使用Java 8中的LocalDate类将日期字符串转换为日期对象,并使用ChronoUnit类计算两个日期之间的天数。
最后,通过判断第一个日期是否早于第二个日期来输出它们的先后关系,并输出它们之间的天数和周数(使用整除运算符将天数转换为周数)。
代码如下:
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;
public class DateIntervalCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入第一个日期(格式如yyyy-MM-dd):");
String dateStr1 = scanner.nextLine();
LocalDate date1 = LocalDate.parse(dateStr1);
System.out.print("请输入第二个日期(格式如yyyy-MM-dd):");
String dateStr2 = scanner.nextLine();
LocalDate date2 = LocalDate.parse(dateStr2);
long daysBetween = ChronoUnit.DAYS.between(date1, date2);
long weeksBetween = daysBetween / 7;
System.out.println(date1.isBefore(date2) ? "第一个日期比第二个日期更早" : "第一个日期比第二个日期更晚");
System.out.println("两个日期间隔" + Math.abs(daysBetween) + "天");
System.out.println("两个日期间隔" + Math.abs(weeksBetween) + "周");
}
}
但输入“2022-6-18 2022-6-1”后,程序非零返回。
我经过查看程序代码,发现问题可能在于日期字符串格式不是标准的“yyyy-MM-dd”格式。在这种情况下,LocalDate.parse()方法会抛出DateTimeParseException异常,导致程序非零返回。
要解决这个问题,可以在程序中指定解析日期字符串的格式。可以使用DateTimeFormatter类定义日期字符串的格式,然后使用该格式解析日期字符串。
下面是修改后的程序代码:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;
public class DateIntervalCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入第一个日期(格式如yyyy-MM-dd):");
String dateStr1 = scanner.nextLine();
LocalDate date1 = LocalDate.parse(dateStr1, DateTimeFormatter.ofPattern("yyyy-M-d"));
System.out.print("请输入第二个日期(格式如yyyy-MM-dd):");
String dateStr2 = scanner.nextLine();
LocalDate date2 = LocalDate.parse(dateStr2, DateTimeFormatter.ofPattern("yyyy-M-d"));
long daysBetween = ChronoUnit.DAYS.between(date1, date2);
long weeksBetween = daysBetween / 7;
System.out.println(date1.isBefore(date2) ? "第一个日期比第二个日期更早" : "第一个日期比第二个日期更晚");
System.out.println("两个日期间隔" + Math.abs(daysBetween) + "天");
System.out.println("两个日期间隔" + Math.abs(weeksBetween) + "周");
}
}
在这个修改后的程序中,使用DateTimeFormatter类指定日期字符串的格式为“yyyy-M-d”,这样就可以正确解析输入的日期字符串。
四、总结
本阶段三次题目集难度偏大,菜单设计复杂困难。建议给出示例代码供学生参考学习,并多提供测试点数据以便学生修改调试代码。

浙公网安备 33010602011771号