一、前言
(1)7-1菜单计价程序-1:
知识点:菜单计价程序,菜品类、菜谱类、点菜记录类、订单类的设计和实现,价格计算方法。
题量:单个题目,包含输入订单和计算总价格。
难度:中等。
(2)7-1菜单计价程序-2:
知识点:菜单计价程序,菜品类、菜谱类、点菜记录类、订单类的设计和实现,价格计算方法,删除记录的处理。
题量:单个题目,包含输入菜单、订单和删除记录,并计算总价格。
难度:中等。
(2)7-1菜单计价程序-3:
知识点:菜单计价程序,菜品类、菜谱类、点菜记录类、订单类的设计和实现,价格计算方法,删除记录的处理,代点菜的处理,折扣的计算。
题量:单个题目,包含输入菜单、订单、删除记录和代点菜信息,并计算每桌的总价格。
难度:较高,涉及到更多的功能和条件判断。
二、设计与分析
(1)第一次作业:
本题是一个简单的菜单计价程序,要求根据输入的订单计算总价格并输出。题目提供了菜品的基础价格和不同份额菜价的计算方法,需要根据这些信息进行计算。
代码: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
// 构造函数
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());
}
}
(2)第二次作业:
第二次作业是一个点菜计价程序,要求根据输入的菜单和订单信息计算总价格,并输出处理信息和总价。
代码:import java.util.*;
class Dish {
String name;
int unit_price;
int getPrice(int portion) {
// int price = (int)(unit_price * portion * 1.5);
// return price%2 == 0 ? price/2 : price/2+1;
double price=unit_price;
if(portion2)
{
price*=1.5;
}
if(portion3)
{
price*=2;
}
return (int) Math.round(price);
}
}
class Menu {
private Map<String, Dish> dishes = new HashMap<>();
Dish searchDish(String dishName) {
return dishes.get(dishName);
}
void addDish(String dishName, int unit_price) {
Dish dish = new Dish();
dish.name = dishName;
dish.unit_price = unit_price;
dishes.put(dishName, dish);
}
}
class Record {
int orderNum;
Dish d;
int portion;
int num;
int getPrice() {
return d.getPrice(portion) * num;
}
}
class Order {
private List
int getTotalPrice() {
int totalPrice = 0;
for (Record r: records) {
totalPrice += r.getPrice();
}
return totalPrice;
}
Record addARecord(int orderNum,String dishName,int portion,int num) {
Record r = new Record();
r.orderNum = orderNum;
r.d = menu.searchDish(dishName);
if (r.d == null) {
System.out.println(dishName+" does not exist");
return null;
}
r.portion = portion;
r.num = num;
records.add(r);
return r;
}
void delARecordByOrderNum(int orderNum) {
Record record = findRecordByNum(orderNum);
if (record == null) {
System.out.println("delete error");
return;
}
records.remove(record);
}
Record findRecordByNum(int orderNum) {
for (Record r: records) {
if (r.orderNum == orderNum) {
return r;
}
}
return null;
}
Menu menu = new Menu();
void setMenu(Menu menu) {
this.menu = menu;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Order order = new Order();
Menu menu = new Menu();
order.setMenu(menu);
while (true) {
String input = sc.nextLine();
if (input.equals("end")) {
break;
}
String[] tokens = input.split(" ");
if (tokens.length == 2) {
String dishName = tokens[0];
int price = Integer.parseInt(tokens[1]);
menu.addDish(dishName, price);
} else if (tokens.length == 4) {
int orderNum = Integer.parseInt(tokens[0]);
String dishName = tokens[1];
int portion = Integer.parseInt(tokens[2]);
int num = Integer.parseInt(tokens[3]);
Record r = order.addARecord(orderNum, dishName, portion, num);
if (r != null) {
System.out.println(r.orderNum+" "+r.d.name+" "+r.getPrice());
}
} else if (tokens.length == 2) {
int orderNum = Integer.parseInt(tokens[0]);
String action = tokens[1];
if (action.equals("delete")) {
order.delARecordByOrderNum(orderNum);
}
}
}
System.out.println(order.getTotalPrice());
}
}
(3)主要分析第三次作业
类图:
实验过程图:
部分代码:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws ParseException {
Scanner scanner = new Scanner(System.in);
Menu menu = new Menu();
ArrayList<Order> orders = new ArrayList<Order>();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss");
SimpleDateFormat timeFormat = new SimpleDateFormat("HHmm");
// 读入菜单
String line;
while (!(line = scanner.nextLine()).equals("end")) {
String[] parts = line.split(" ");
String dishName = parts[0];
int unit_price = Integer.parseInt(parts[1]);
menu.addDish(dishName, unit_price);
}
// 读入订单
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.equals("end")) {
break;
}
String[] parts = line.split(" ");
String orderTimeStr = parts[0] + " " + parts[1];
Date orderTime = dateFormat.parse(orderTimeStr);
Order order = new Order(orderTime);
for (int i = 2; i < parts.length; i++) {
String[] dishParts = parts[i].split(":");
String dishName = dishParts[0];
int amount = Integer.parseInt(dishParts[1]);
order.addDish(menu.getDish(dishName), amount);
}
orders.add(order);
}
// 计算每个订单的总价和打折后的价钱,并输出
for (Order order : orders) {
int totalPrice = order.getTotalPrice();
Calendar calendar = Calendar.getInstance();
calendar.setTime(order.getOrderTime());
int hour = calendar.get(Calendar.HOUR_OF_DAY);
double discount = hour >= 9 && hour <= 11 ? 0.7 : 1.0; // 判断是否打折
int discountedPrice = (int) Math.round(totalPrice * discount);
System.out.println(order.getOrderTime() + " " + discountedPrice);
}
}
}
class Menu {
HashMap<String, Dish> dishes;
public Menu() {
dishes = new HashMap<String, Dish>();
}
public Dish searchDish(String dishName) {
return dishes.get(dishName);
}
public Dish addDish(String dishName, int unit_price) {
Dish dish = new Dish(dishName, unit_price);
dishes.put(dishName, dish);
return dish;
}
}
class Record {
int orderNum;
Dish dish;
int portion;
public Record(int orderNum, Dish dish, int portion) {
this.orderNum = orderNum;
this.dish = dish;
this.portion = portion;
}
public int getPrice() {
return dish.getPrice(portion);
}
}
class Order {
ArrayList<Record> records;
public Order() {
records = new ArrayList<Record>();
}
public int getTotalPrice() {
int totalPrice = 0;
for (Record record : records) {
totalPrice += record.getPrice();
}
return totalPrice;
}
public Record addARecord(int orderNum, Dish dish, int portion, int num) {
Record record = new Record(orderNum, dish, portion);
records.add(record);
return record;
}
public void delARecordByOrderNum(int orderNum) {
for (int i = 0; i < records.size(); i++) {
if (records.get(i).orderNum == orderNum) {
records.remove(i);
return;
}
}
System.out.println("delete error");
}
public Record findRecordByNum(int orderNum) {
for (Record record : records) {
if (record.orderNum == orderNum) {
return record;
}
}
return null;
}
}
三、采坑心得(以第三次作业为主)
1.理解题目要求:在开始实验之前,确保你充分理解了题目要求和功能需求。仔细阅读每个输入和输出的格式要求,并理解每个类的功能和关系。
2.设计合适的数据结构:根据题目要求和功能需求,设计适合的数据结构来存储菜单、订单和记录的信息。菜单可以使用一个菜品数组来存储,订单可以使用一个记录数组来存储。
3.菜单的基础价格:注意题目中提到如果有多条相同菜名的记录,菜品的基础价格以最后一条记录为准。在实现菜单类时,需要考虑这个要求,确保每个菜名对应的基础价格正确。
4.计算菜品价格:在菜品类中实现计算菜品价格的方法。根据输入的份额(1/2/3代表小/中/大份),按照题目中给出的计算方法进行计算,并考虑四舍五入的规则。
5.订单记录的添加和删除:在订单类中实现添加和删除记录的功能。根据输入的订单信息,可以通过菜单类查找对应的菜品信息,并创建记录对象进行添加。对于删除记录,需要检查序号的有效性并进行相应处理。
6.代点菜信息的处理:根据题目要求,代点菜信息是在当前桌为另一桌点菜,所以需要在订单类中实现处理代点菜信息的功能。根据代点菜的桌号和序号,找到对应的菜品信息,并计算价格。
7.输出结果的格式:按照题目要求,输出每一桌的订单记录处理信息和总价。确保输出的格式正确,并按照输入的先后顺序输出结果。
四、主要困难以及改进建(以第三次作业为主)
(1)主要困难分析:
- 数据结构设计:题目中涉及到多个类的设计,包括菜品类、菜谱类、点菜记录类、订单类等。在解题过程中,需要合理设计这些类之间的关系,确保数据的正确传递和处理。
- 输入解析:输入的格式较为复杂,包括桌号标识、菜品记录、点菜记录、删除记录和代点菜信息等。在解析输入时,需要正确识别各个部分,并将其转换为相应的数据结构进行处理。
- 代点菜信息处理:代点菜功能涉及到跨桌点菜和价格计算,需要正确处理代点菜信息,并将代点菜的价格计算在当前桌上。
- 折扣计算:根据营业时间和折扣规则,计算每桌的折扣价格。需要根据时间范围进行判断,并正确计算折扣价格。
(2)改进建议:
1.在输入解析方面,可以考虑使用正则表达式或字符串分割等方法,针对不同的输入格式进行匹配和解析,提取出所需的数据并进行相应处理。可以编写相应的解析函数或方法,将复杂的解析过程封装起来,提高代码的可复用性。
2.对于代点菜信息的处理,可以设计一个代点菜的类或方法,用于处理跨桌点菜的逻辑。在代点菜时,可以根据代点菜的桌号找到对应的订单,并将代点菜的价格计算在当前桌上,最后统一计算当前桌的总价。
五、总结
在本阶段的三次题目集中,我学到了如何设计和实现不同类型的程序,包括计算器、菜单计价程序等。通过完成这些题目,我掌握了编写基本的逻辑和算法,了解了面向对象编程的基本概念和设计模式。我还学会了使用类和对象进行数据的封装和操作,以及如何处理输入输出和异常情况。
在实践中,我发现自己对编程语言的理解和熟练程度有了一定的提高。我学会了如何根据问题的要求进行程序设计,将问题分解为适当的类和方法,并进行模块化的开发。我也体会到了调试和测试的重要性,以及如何通过调试和测试来发现和修复程序中的错误。
(1)需要进一步学习和研究的地方:
1.数据结构和算法:在本阶段的题目中,涉及到了一些简单的算法,如计算总价、查找菜品等。然而,在面对更复杂的问题时,我意识到自己对数据结构和算法的理解还不够深入。因此,我计划进一步学习和研究数据结构和算法的知识,以提高程序的效率和性能。
2.更多编程语言的学习:本阶段的题目中使用了特定的编程语言进行实现,但在实际开发中可能会遇到其他编程语言。为了扩展自己的技能,我希望学习更多的编程语言,并了解它们的特性和用途,以便能够更灵活地选择合适的工具进行开发。
(2)改进建议及意见:
1.强调实践与理论的结合:在课程中,更多地强调实践与理论的结合将会使学习效果更好。通过实际的编程任务和项目实践,学生可以更深入地理解和应用所学的知识,并培养解决实际问题的能力。
2.提供更多的编程练习和挑战:编程是一个需要不断练习和挑战的过程。为了加强学生的编程能力,可以提供更多的编程练习和挑战题目,涵盖不同的难度和领域,让学生有机会锻炼和提高自己的编程技巧。
3.提供更多实际案例和实际应用:除了题目集中的小型程序,可以引入一些实际的案例和实际应用,让学生了解编程