JAVA PTA1~3题目集总结

一、前言:

  第一次题目集主要让我熟悉使用Java语法,题目比较简单,用C语言的逻辑和Java语法全部完成了。题量适中,难度适中。

  第二次题目集开始很难,出现了两份菜单设计和jmu-java-日期类的基本使用。努力努力学习别人的代码,成功写出来了。题量一般,有点难度。

  第三次题目集开始很很难,出现了升级版菜单设计和一堆更难的题目。努力努力也写不出菜单,别的题目写出来了。题量偏大,菜单难度极大,其余题目难度偏大。

二、题目分析

7-1 菜单计价程序-1
分数 30
作者 蔡轲
单位 南昌航空大学

某饭店提供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
 
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
 
题目分析:
  1. 类的设计与实现:需要设计并实现 DishMenuRecordOrder 这几个类来表示菜品、菜谱、点菜记录和订单。

  2. 字符串操作:涉及菜品名称的存储、比较和解析。

  3. 数组操作:在菜谱和订单中使用数组来保存多个菜品或点菜记录。

  4. 循环和条件语句:用于在菜谱中查找菜品信息和计算订单总价。

  5. 方法设计:每个类需要设计相应的方法来实现特定的功能,如计算菜品价格、查找菜品、计算点菜记录价格等。

  6. 对象关联:类之间可能存在关联关系,如 Order 类中需要使用 Menu 类的方法来获取菜品信息。

  7. 异常处理:需要处理无法识别的菜名,并显示错误信息。

  8. 小数处理:根据要求,需要对价格进行四舍五入处理,可以使用 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());
    }
}
7-2 菜单计价程序-2
分数 40
作者 蔡轲
单位 南昌航空大学

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"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. 输出格式:按照要求输出每条点菜记录的处理信息,包括序号、菜名和价格;如果有不能识别的菜名则输出错误信息;最后输出订单的总价。

 

7-1 菜单计价程序-3
分数 30
作者 蔡轲
单位 南昌航空大学

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"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
 
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
 

与前者不同的地方:

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;
}

三、遇到的困难与问题

(1)7-3 jmu-java-日期类的基本使用
  1. 给定一个日期,判定是否为合法日期。如果合法,判断该年是否闰年,该日期是当年第几天、当月第几天、当周第几天、。
  2. 给定起始日期与结束日期,判定日期是否合法且结束日期是否早于起始日期。如果均合法,输出结束日期与起始日期之间的相差的天数、月数、念书。
 
在该题处,运用了jmu-java-日期类。但是我还没有学过、见过该类的使用,看到题目时毫无头绪。不过通过上网查询资料并学习参考代码,才勉强能够照样读取处理日期数据。
 
 (2)用Java编写程序,从键盘输入两个日期,格式如:2022-06-18。判断两个日期的先后,并输出它们之间间隔的天数、周数(不足一周按0计算)。 1.输入两行,每行输入一个日期,日期格式如:2022-06-18 2.第一行输出:第一个日期比第二个日期更早(晚) 第二行输出:两个日期间隔XX天 第三行输出:两个日期间隔XX周
 
我使用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”,这样就可以正确解析输入的日期字符串。

四、总结

本阶段三次题目集难度偏大,菜单设计复杂困难。建议给出示例代码供学生参考学习,并多提供测试点数据以便学生修改调试代码。

 
 
posted @ 2023-05-16 13:05  B-006荣  阅读(57)  评论(0)    收藏  举报