BLOG-2

(1)前言

本次BLOG将对题目集4,5及期中考试相关题目进行分析与总结,以下是相关的前言部分。

题目集4,5各自只有一个题目,分别是菜单计价程序-4和菜单计价程序-5,这也是菜单计价程序的最后两个相关题目,难度嘛,可以说很难了。

而期中考试的题目有四个,分别是测验1-圆类设计,测验2-类结构设计,测验3-继承与多态,测验4-抽象类与接口。

测试1的难度属于简单的,不过有点问题我之后在“踩坑心得”会说,特别的知识点没有,都是基础。

测试2的难度也很简单,实际上测试3的难度也不大,主要考察的还是类的创建,继承关系和多态的应用。

测试4的难度就属于中等偏上了,主要因为我不熟悉接口的应用。

(2)设计与分析

以下我先给出菜单计价程序4的源码。

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Calendar;
import java.util.Date;
public class Main {
    public static void main(String[] args) {
        Work work = new Work();
        work.play();
    }
}
class Work {
    boolean Stop = false;  //用来确定订单和菜单混杂在一起的情况
    Menu menu;  //单位菜单
    Record record;  //单位记录
    Table table; //单位座位
    ArrayList<Table> tables = new ArrayList<>();  //座位数组

    Work() {    //初始化,用来创建基本的类数组
        //只能用一个菜单,别单位化
        //对所有的table都开放
        menu = new Menu();
        //单位化,订单?   Record应该是必须得单位化
        record = new Record();
        //定义一个存储Table的一个ArrayList —— tables的动态数组
        tables = new ArrayList<>();
    }

    public void play() {  //play 菜单程序主要运行的程序
        Scanner in = new Scanner(System.in);
        while (true) {
            String Line = in.nextLine();
            if (Line.equals("end")) {
                break;
            }
            String[] LineArray = Line.split(" ");
            if (LineArray.length == 2) { //一个空格
                if (LineArray[1].equals("delete")) {  //删除订单
                    int num = Integer.parseInt(LineArray[0]);
                    if (table.deletes.contains(num)) {
                        System.out.println("deduplication " + num);
                        continue;
                    }
                    else {
                        Record pp =table.order.find(num);
                        table.order.delARecordByOrderNum(num);
                        table.deletes.add(num);
                    }
                } else {   //菜单添加
                    if (!Stop) { //菜单还没有输出完
                        try {
                            int x = Integer.parseInt(LineArray[1]);
                        }
                        catch (Exception e1) {
                            System.out.println("wrong format");
                            continue;
                        }
                        Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]));
                        menu.addDish(dish);
                    }
                    else {
                        System.out.println("invalid dish");
                    }
                }
                //continue;
            }
            else if (LineArray.length == 3) {
                if (LineArray[2].equals("T")) { //特色菜
                    Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]),LineArray[2]);
                    menu.addDish(dish);
                }
            }
            else if (LineArray.length == 4) {   //三个空格,四个数据
                if (LineArray[0].equals("table")) { //座号
                    try {
                        table = new Table(LineArray[1], LineArray[2], LineArray[3],menu);
                        if (table.time_error) {
                            int yy = Integer.parseInt(LineArray[2]);  //用来故意报错
                        }
                        table.Discount(); //设定该table的折扣
                        System.out.println("table " + table.num + ": ");
                        tables.add(table);
                        Stop = true;
                    }
                    catch (Exception e2) {
                        System.out.println("wrong format");
                        break;
                    }
                } else { //添加订单
                    int number = Integer.parseInt(LineArray[0]);
                    int portion = Integer.parseInt(LineArray[2]);
                    int num = Integer.parseInt(LineArray[3]);
                    if ((3<portion && portion<10)|| portion<1) {
                        System.out.println(number + " portion out of range " + portion);
                        if (num>15) {
                            System.out.println(number + " num out of range " + num);
                        }
                        continue;
                    }
                    if (portion>=10) {
                        System.out.println("not a valid time period");
                        if (num>15) {
                            System.out.println(number + " num out of range " + num);
                        }
                        continue;
                    }
                    if (num>15) {
                        System.out.println(number + " num out of range " + num);
                        continue;
                    }
                    record = new Record(number, LineArray[1], portion, num);  //初始化单位record的序号,菜名,份额,数量
                    if (menu.searchDish(LineArray[1]) != null) {   //有该菜
                        Record oop = table.order.find_ByName(LineArray[1]); //查看Order中是否有该菜名的Record
                        if (oop!=null && oop.portion == portion) { //如果有该菜名的Record并且portion相等
                            oop.num += num;
                            continue;
                        }
                        record.d = menu.searchDish(LineArray[1]);  //获得该菜名的Dish类
                        table.order.addARecord(record);   //答案在if的前面???
                        int under_number = table.order.records.size()-1;   //存储最后一个的table的下标
                        //往record中添加菜品,提供单价
                        //在record里面添加菜品的单价和名字
                        table.order.records.get(under_number).d = menu.searchDish(LineArray[1]);
                        //获取record的单个总价
                        int price = table.order.records.get(under_number).getPrice();
                        //输出单个record的表出
                        System.out.println(table.order.records.get(under_number).orderNum + " " +
                                LineArray[1] + " " +price);
                    }
                }
                //continue;
            }
            else if (LineArray.length == 5) { //代点菜
                try {
                    int number = Integer.parseInt(LineArray[1]);
                    int portion = Integer.parseInt(LineArray[3]);
                    int num = Integer.parseInt(LineArray[4]);
                    record = new Record(number, LineArray[2], portion, num);
                    if (menu.searchDish(LineArray[2])!=null) {   //菜单内有该菜品
                        //添加record
                        table.order.addARecord(record);
                        int under_number = table.order.records.size()-1;
                        //设定record的菜品单价
                        table.order.records.get(under_number).d = menu.searchDish(LineArray[2]);
                        int price = table.order.records.get(under_number).getPrice();
                        System.out.println(number + " table " + table.num + " pay for table " + LineArray[0] + price);
                    }
                }
                catch (Exception e2){
                    System.out.println("wrong format");
                    break;
                }
            }
        }
        for (int i = 0 ; i < tables.size() ; i++) {
            tables.get(i).GetToTalPrice();
        }
    }
}
//    菜品类:对应菜谱上一道菜的信息。
class Dish { //封装
    Dish() { } //空构造器
    Dish(String dishName) {
        this.name = dishName;
    }
    Dish(String dishName , int unit_price) {
        this.name = dishName;
        this.unit_price = unit_price;
    } //普通菜的构造器
    Dish(String dishName , int unit_price , String pp) {
        this.name = dishName;
        this.unit_price = unit_price;
        if (pp.equals("T")) {
            TT = true;
        }
    } //特色菜的构造器
    private String name;//菜品名称
    private int unit_price; //单价
    private boolean TT = false; //特色菜标志
    public int getPrice(int portion) {
        double[] size = {1,1.5,2};
        double Price = 0;
        switch (portion) {
            case 1:
                Price = this.unit_price * size[0];
                break;
            case 2:
                Price = this.unit_price * size[1];
                break;
            case 3:
                Price = this.unit_price * size[2];
                break;
            default:;
        }
        return ((int)Math.round(Price));
    }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }
    //封装的读取器
    public String getName() {
        return name;
    }//读取Name
    public int getUnit_price() {
        return unit_price;
    }//读取单价
    public boolean getTT() {
        return TT;
    }// 读取特色菜的标志
    public void setUnit_price(int unit_price) {
        this.unit_price = unit_price;
    }  //重新定义单价
}
//菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
class Menu {
    Menu() {
    }
    ArrayList<Dish> dishes = new ArrayList<>(); //菜品数组,保存所有菜品信息
    public Dish searchDish(String dishName) {
        boolean find = false;
        for (Dish dish : dishes){
            if (dish.getName().equals(dishName)) {
                find = true;
                return dish;
            } //如果找到就返回dish的类信息
        }
        System.out.println(dishName + " does not exist");
        return null;  //没有就返回null,用于判断是否找到
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    public void addDish(Dish dish) { //开始为返回Dish类???为什么???
        if (search(dish.getName())) {
            Dish pp = searchDish(dish.getName());
            pp.setUnit_price(dish.getUnit_price());
        }//如果发现有该菜品则重新定义该单价
        else {
            dishes.add(dish);
        }//没有发现则直接加入dishes列表里面去
    }   //添加一道菜品信息
    public boolean search(String dishName) {
        boolean find = false;
        for (Dish dish : dishes){
            if (dish.getName().equals(dishName)) {
                find = true;
                break;
            } //如果找到就返回boolean
        }
        return find;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}
//希望能够实现存储每一个table的基本信息
//包括该table的订单和记录
class Table {
    ArrayList<Integer> deletes = new ArrayList<>();
    Menu menu = new Menu();
    int num;//座序号
//    int sum = 0;//总价钱
    Calendar data = Calendar.getInstance();//时间
    Order order;//订单
    Record record;//记录
    double discount = -1;
    int year,month,day,hours,minute,second;   //时间存储Date的参数
    int week; //用来存储星期数目的
    boolean time_error = false;   //保存time的格式对错
    Table(String num , String Day , String Time,Menu menu) {
        this.num = Integer.parseInt(num);  //保存序号

        String[] dataString = Day.split("/"); //保存日期
        this.year = Integer.parseInt(dataString[0]);
        this.month = Integer.parseInt(dataString[1]);
        this.day = Integer.parseInt(dataString[2]);

        String[] timeString = Time.split("/"); //保存时间
        this.hours = Integer.parseInt(timeString[0]);
        this.minute = Integer.parseInt(timeString[1]);
        this.second = Integer.parseInt(timeString[2]);

        try {
            for (int i = 0 ; i < 3 ; i++) {
                if (timeString[i].length()>2) {
                    time_error = true;
                    break;
                }
            }
            if (year%1000==0) {
                System.out.println(num + " date error");
            }
            else {
                Calendar data_start = Calendar.getInstance();
                data_start.set(2022,1,1);
                Calendar data_end = Calendar.getInstance();
                data_end.set(2023,12,31);
                data.set(year,month,day,hours,minute,second);
                if (data.after(data_end) || data.before(data_start)) {
                    System.out.println("not a valid time period");
                }
                else {
                    boolean isFirstSunday = (data.getFirstDayOfWeek() == Calendar.SUNDAY);
                    week = data.get(Calendar.DAY_OF_WEEK);
                    //若一周第一天为星期天,则-1
                    if(isFirstSunday){
                        week = week - 1;
                        if(week == 0){
                            week = 7;
                        }
                    }
                    order = new Order(); //同时构造Order类和Record类
                    record = new Record();
                    this.menu = menu;
                }
            }
        }
        catch (Exception e1) {
            System.out.println(num + " date error");
        }
    }
    public void GetToTalPrice() {
        if (discount<0) { //没有折扣,说明不在营业时间之内
            System.out.println("table " + num + " out of opening hours");
        }
        else { //有折扣,说明在营业时间之内
            int primer_uuu = 0;
            int uuu = 0;
            for (int i = 0 ; i < order.records.size() ; i++) {
                if (!deletes.contains(order.records.get(i).orderNum)) {   //把没有删除的进行相加
                    primer_uuu = primer_uuu + order.records.get(i).getPrice();
                    if (order.records.get(i).d.getTT()) {   //是特色菜,特别处理折扣
                        uuu = uuu + (int)Math.round(primer_uuu * 0.7);
                    }
                    else {     //不是特色菜
                        uuu = uuu + (int)Math.round(primer_uuu * discount);
                    }
                }
            }
//            int sum_primer = (int)sum;
//            sum = (int)Math.round(sum*discount);
            System.out.println("table " + num + ": " + primer_uuu + " " + uuu);
        }
    }
    public void Discount() {
        if (week>=1 && week<=5) {   //在工作日的时间内
            if (hours>=17 && hours<20) {
                discount = 0.8;
            }
            else if (hours==20 && minute<30){
                discount = 0.8;
            }
            else if (hours==20 && minute==30 && second==0){
                discount = 0.8;
            }
            else if ((hours>=11 && hours <=13) || (hours==10 && minute>=30)){
                discount = 0.6;
            }
            else if (hours==14 && minute<30) {
                discount = 0.6;
            }
            else if (hours==14 && minute==30 && second==0) {
                discount = 0.6;
            }
        }
        else {   //周末
            if (hours>=10 && hours<=20) {
                discount = 1.0;
            }
            else if (hours==9 && minute>=30){
                discount = 1.0;
            }
            else if ((hours==21 && minute<30) || (hours==21 && minute==30 && second==0)){
                discount = 1.0;
            }
        }
    } //判断是否在营业的时间内
}
//订单类:保存用户点的所有菜的信息。
class Order {
    Order() {} //构造器
    ArrayList<Record> records = new ArrayList<>();//保存订单上每一道的记录
    public int getTotalPrice() {
        int sum = 0;
        for (Record pp : records){
            sum=sum+pp.getPrice();
        }
        return sum;
        //打算放到Table里面进行相对应的Date判断,以便进行相对应的日期优惠!!!
        //还是使用它,先计算总价位,再来对日期进行相对应的打折
    }//计算订单的总价

    public void addARecord(Record pp) { //原来为Record返回类型
        records.add(pp);
    }//添加一条菜品信息到订单中。

    public void delARecordByOrderNum(int orderNum) {  //例子为int类???
        if (findRecordByNum(orderNum)) {
            records.remove(find(orderNum));
        }//找到删除
        else {
            System.out.println("delete error");
        }//未找到则输出对应的信息
    }//根据序号删除一条记录

    public boolean findRecordByNum(int orderNum) {  //原来为void类型
        for (Record pp : records) {
            if (pp.orderNum == orderNum) {
                return true;
            }
        }
        return false;
    }//根据序号查找一条记录
    public Record find (int orderNum) {  //可以通过订单进行记录的查找
        for (Record pp : records) {
            if (pp.orderNum == orderNum) {
                return pp;
            }
        }
        return null;
    }//返回对应的Record类
    public Record find_ByName(String name) {   //通过名字查找Order中的Record
        for (Record pp : records) {
            if (pp.d.getName().equals(name)){
                return pp;
            }
        }
        return null;
    }
}
//点菜记录类:保存订单上的一道菜品记录
class Record {
    Record(){
    } //空构造器
    Record(int orderNum,String dishName,int portion,int num) { //构造器
        this.orderNum = orderNum;
        this.portion = portion;
        this.d = new Dish(dishName);
        this.num = num;
        setDish(dishName);
    }  //非空构造器
    int orderNum;//序号
    Dish d;//菜品
    public void setDish(String dishName) {
        d = new Dish(dishName);
    }
    int portion;//份额(1/2/3代表小/中/大份)
    int num; //份数,用来存储份数
    public int getPrice() {
        int Price = 0;
        Price = d.getPrice(portion)*num;
        return Price;
    }//计价,计算本条记录的价格,返回int单个菜品的总价
    //注意这里是未打折的总价
}

  菜单计价程序4相对于3又有了很多新增内容。

比菜单计价系列-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折, 周末全价。

注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:

计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。

最后将所有记录的菜价累加得到整桌菜的价格。

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Calendar;
import java.util.Date;
public class Main {
    public static void main(String[] args) {
        Work work = new Work();
        work.play();
    }
}
class Work {
    boolean Stop = false;  //用来确定订单和菜单混杂在一起的情况
    Menu menu;  //单位菜单
    Record record;  //单位记录
    Table table; //单位座位
    ArrayList<Table> tables = new ArrayList<>();  //座位数组

    Work() {    //初始化,用来创建基本的类数组
        //只能用一个菜单,别单位化
        //对所有的table都开放
        menu = new Menu();
        //单位化,订单?   Record应该是必须得单位化
        record = new Record();
        //定义一个存储Table的一个ArrayList —— tables的动态数组
        tables = new ArrayList<>();
    }

    public void play() {  //play 菜单程序主要运行的程序
        Scanner in = new Scanner(System.in);
        while (true) {
            String Line = in.nextLine();
            if (Line.equals("end")) {
                break;
            }
            String[] LineArray = Line.split(" ");
            if (LineArray.length == 2) { //一个空格
                if (LineArray[1].equals("delete")) {  //删除订单
                    int num = Integer.parseInt(LineArray[0]);
                    if (table.deletes.contains(num)) {
                        System.out.println("deduplication " + num);
                        continue;
                    }
                    else {
                        Record pp =table.order.find(num);
                        table.order.delARecordByOrderNum(num);
                        table.deletes.add(num);
                    }
                } else {   //菜单添加
                    if (!Stop) { //菜单还没有输出完
                        try {
                            int x = Integer.parseInt(LineArray[1]);
                        }
                        catch (Exception e1) {
                            System.out.println("wrong format");
                            continue;
                        }
                        Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]));
                        menu.addDish(dish);
                    }
                    else {
                        System.out.println("invalid dish");
                    }
                }
                //continue;
            }
            else if (LineArray.length == 3) {
                if (LineArray[2].equals("T")) { //特色菜
                    Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]),LineArray[2]);
                    menu.addDish(dish);
                }
            }
            else if (LineArray.length == 4) {   //三个空格,四个数据
                if (LineArray[0].equals("table")) { //座号
                    try {
                        table = new Table(LineArray[1], LineArray[2], LineArray[3],menu);
                        if (table.time_error) {
                            int yy = Integer.parseInt(LineArray[2]);  //用来故意报错
                        }
                        table.Discount(); //设定该table的折扣
                        System.out.println("table " + table.num + ": ");
                        tables.add(table);
                        Stop = true;
                    }
                    catch (Exception e2) {
                        System.out.println("wrong format");
                        break;
                    }
                } else { //添加订单
                    int number = Integer.parseInt(LineArray[0]);
                    int portion = Integer.parseInt(LineArray[2]);
                    int num = Integer.parseInt(LineArray[3]);
                    if ((3<portion && portion<10)|| portion<1) {
                        System.out.println(number + " portion out of range " + portion);
                        if (num>15) {
                            System.out.println(number + " num out of range " + num);
                        }
                        continue;
                    }
                    if (portion>=10) {
                        System.out.println("not a valid time period");
                        if (num>15) {
                            System.out.println(number + " num out of range " + num);
                        }
                        continue;
                    }
                    if (num>15) {
                        System.out.println(number + " num out of range " + num);
                        continue;
                    }
                    record = new Record(number, LineArray[1], portion, num);  //初始化单位record的序号,菜名,份额,数量
                    if (menu.searchDish(LineArray[1]) != null) {   //有该菜
                        Record oop = table.order.find_ByName(LineArray[1]); //查看Order中是否有该菜名的Record
                        if (oop!=null && oop.portion == portion) { //如果有该菜名的Record并且portion相等
                            oop.num += num;
                            continue;
                        }
                        record.d = menu.searchDish(LineArray[1]);  //获得该菜名的Dish类
                        table.order.addARecord(record);   //答案在if的前面???
                        int under_number = table.order.records.size()-1;   //存储最后一个的table的下标
                        //往record中添加菜品,提供单价
                        //在record里面添加菜品的单价和名字
                        table.order.records.get(under_number).d = menu.searchDish(LineArray[1]);
                        //获取record的单个总价
                        int price = table.order.records.get(under_number).getPrice();
                        //输出单个record的表出
                        System.out.println(table.order.records.get(under_number).orderNum + " " +
                                LineArray[1] + " " +price);
                    }
                }
                //continue;
            }
            else if (LineArray.length == 5) { //代点菜
                try {
                    int number = Integer.parseInt(LineArray[1]);
                    int portion = Integer.parseInt(LineArray[3]);
                    int num = Integer.parseInt(LineArray[4]);
                    record = new Record(number, LineArray[2], portion, num);
                    if (menu.searchDish(LineArray[2])!=null) {   //菜单内有该菜品
                        //添加record
                        table.order.addARecord(record);
                        int under_number = table.order.records.size()-1;
                        //设定record的菜品单价
                        table.order.records.get(under_number).d = menu.searchDish(LineArray[2]);
                        int price = table.order.records.get(under_number).getPrice();
                        System.out.println(number + " table " + table.num + " pay for table " + LineArray[0] + price);
                    }
                }
                catch (Exception e2){
                    System.out.println("wrong format");
                    break;
                }
            }
        }
        for (int i = 0 ; i < tables.size() ; i++) {
            tables.get(i).GetToTalPrice();
        }
    }
}
//    菜品类:对应菜谱上一道菜的信息。
class Dish { //封装
    Dish() { } //空构造器
    Dish(String dishName) {
        this.name = dishName;
    }
    Dish(String dishName , int unit_price) {
        this.name = dishName;
        this.unit_price = unit_price;
    } //普通菜的构造器
    Dish(String dishName , int unit_price , String pp) {
        this.name = dishName;
        this.unit_price = unit_price;
        if (pp.equals("T")) {
            TT = true;
        }
    } //特色菜的构造器
    private String name;//菜品名称
    private int unit_price; //单价
    private boolean TT = false; //特色菜标志
    public int getPrice(int portion) {
        double[] size = {1,1.5,2};
        double Price = 0;
        switch (portion) {
            case 1:
                Price = this.unit_price * size[0];
                break;
            case 2:
                Price = this.unit_price * size[1];
                break;
            case 3:
                Price = this.unit_price * size[2];
                break;
            default:;
        }
        return ((int)Math.round(Price));
    }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }
    //封装的读取器
    public String getName() {
        return name;
    }//读取Name
    public int getUnit_price() {
        return unit_price;
    }//读取单价
    public boolean getTT() {
        return TT;
    }// 读取特色菜的标志
    public void setUnit_price(int unit_price) {
        this.unit_price = unit_price;
    }  //重新定义单价
}
//菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
class Menu {
    Menu() {
    }
    ArrayList<Dish> dishes = new ArrayList<>(); //菜品数组,保存所有菜品信息
    public Dish searchDish(String dishName) {
        boolean find = false;
        for (Dish dish : dishes){
            if (dish.getName().equals(dishName)) {
                find = true;
                return dish;
            } //如果找到就返回dish的类信息
        }
        System.out.println(dishName + " does not exist");
        return null;  //没有就返回null,用于判断是否找到
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    public void addDish(Dish dish) { //开始为返回Dish类???为什么???
        if (search(dish.getName())) {
            Dish pp = searchDish(dish.getName());
            pp.setUnit_price(dish.getUnit_price());
        }//如果发现有该菜品则重新定义该单价
        else {
            dishes.add(dish);
        }//没有发现则直接加入dishes列表里面去
    }   //添加一道菜品信息
    public boolean search(String dishName) {
        boolean find = false;
        for (Dish dish : dishes){
            if (dish.getName().equals(dishName)) {
                find = true;
                break;
            } //如果找到就返回boolean
        }
        return find;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}
//希望能够实现存储每一个table的基本信息
//包括该table的订单和记录
class Table {
    ArrayList<Integer> deletes = new ArrayList<>();
    Menu menu = new Menu();
    int num;//座序号
//    int sum = 0;//总价钱
    Calendar data = Calendar.getInstance();//时间
    Order order;//订单
    Record record;//记录
    double discount = -1;
    int year,month,day,hours,minute,second;   //时间存储Date的参数
    int week; //用来存储星期数目的
    boolean time_error = false;   //保存time的格式对错
    Table(String num , String Day , String Time,Menu menu) {
        this.num = Integer.parseInt(num);  //保存序号

        String[] dataString = Day.split("/"); //保存日期
        this.year = Integer.parseInt(dataString[0]);
        this.month = Integer.parseInt(dataString[1]);
        this.day = Integer.parseInt(dataString[2]);

        String[] timeString = Time.split("/"); //保存时间
        this.hours = Integer.parseInt(timeString[0]);
        this.minute = Integer.parseInt(timeString[1]);
        this.second = Integer.parseInt(timeString[2]);

        try {
            for (int i = 0 ; i < 3 ; i++) {
                if (timeString[i].length()>2) {
                    time_error = true;
                    break;
                }
            }
            if (year%1000==0) {
                System.out.println(num + " date error");
            }
            else {
                Calendar data_start = Calendar.getInstance();
                data_start.set(2022,1,1);
                Calendar data_end = Calendar.getInstance();
                data_end.set(2023,12,31);
                data.set(year,month,day,hours,minute,second);
                if (data.after(data_end) || data.before(data_start)) {
                    System.out.println("not a valid time period");
                }
                else {
                    boolean isFirstSunday = (data.getFirstDayOfWeek() == Calendar.SUNDAY);
                    week = data.get(Calendar.DAY_OF_WEEK);
                    //若一周第一天为星期天,则-1
                    if(isFirstSunday){
                        week = week - 1;
                        if(week == 0){
                            week = 7;
                        }
                    }
                    order = new Order(); //同时构造Order类和Record类
                    record = new Record();
                    this.menu = menu;
                }
            }
        }
        catch (Exception e1) {
            System.out.println(num + " date error");
        }
    }
    public void GetToTalPrice() {
        if (discount<0) { //没有折扣,说明不在营业时间之内
            System.out.println("table " + num + " out of opening hours");
        }
        else { //有折扣,说明在营业时间之内
            int primer_uuu = 0;
            int uuu = 0;
            for (int i = 0 ; i < order.records.size() ; i++) {
                if (!deletes.contains(order.records.get(i).orderNum)) {   //把没有删除的进行相加
                    primer_uuu = primer_uuu + order.records.get(i).getPrice();
                    if (order.records.get(i).d.getTT()) {   //是特色菜,特别处理折扣
                        uuu = uuu + (int)Math.round(primer_uuu * 0.7);
                    }
                    else {     //不是特色菜
                        uuu = uuu + (int)Math.round(primer_uuu * discount);
                    }
                }
            }
//            int sum_primer = (int)sum;
//            sum = (int)Math.round(sum*discount);
            System.out.println("table " + num + ": " + primer_uuu + " " + uuu);
        }
    }
    public void Discount() {
        if (week>=1 && week<=5) {   //在工作日的时间内
            if (hours>=17 && hours<20) {
                discount = 0.8;
            }
            else if (hours==20 && minute<30){
                discount = 0.8;
            }
            else if (hours==20 && minute==30 && second==0){
                discount = 0.8;
            }
            else if ((hours>=11 && hours <=13) || (hours==10 && minute>=30)){
                discount = 0.6;
            }
            else if (hours==14 && minute<30) {
                discount = 0.6;
            }
            else if (hours==14 && minute==30 && second==0) {
                discount = 0.6;
            }
        }
        else {   //周末
            if (hours>=10 && hours<=20) {
                discount = 1.0;
            }
            else if (hours==9 && minute>=30){
                discount = 1.0;
            }
            else if ((hours==21 && minute<30) || (hours==21 && minute==30 && second==0)){
                discount = 1.0;
            }
        }
    } //判断是否在营业的时间内
}
//订单类:保存用户点的所有菜的信息。
class Order {
    Order() {} //构造器
    ArrayList<Record> records = new ArrayList<>();//保存订单上每一道的记录
    public int getTotalPrice() {
        int sum = 0;
        for (Record pp : records){
            sum=sum+pp.getPrice();
        }
        return sum;
        //打算放到Table里面进行相对应的Date判断,以便进行相对应的日期优惠!!!
        //还是使用它,先计算总价位,再来对日期进行相对应的打折
    }//计算订单的总价

    public void addARecord(Record pp) { //原来为Record返回类型
        records.add(pp);
    }//添加一条菜品信息到订单中。

    public void delARecordByOrderNum(int orderNum) {  //例子为int类???
        if (findRecordByNum(orderNum)) {
            records.remove(find(orderNum));
        }//找到删除
        else {
            System.out.println("delete error");
        }//未找到则输出对应的信息
    }//根据序号删除一条记录

    public boolean findRecordByNum(int orderNum) {  //原来为void类型
        for (Record pp : records) {
            if (pp.orderNum == orderNum) {
                return true;
            }
        }
        return false;
    }//根据序号查找一条记录
    public Record find (int orderNum) {  //可以通过订单进行记录的查找
        for (Record pp : records) {
            if (pp.orderNum == orderNum) {
                return pp;
            }
        }
        return null;
    }//返回对应的Record类
    public Record find_ByName(String name) {   //通过名字查找Order中的Record
        for (Record pp : records) {
            if (pp.d.getName().equals(name)){
                return pp;
            }
        }
        return null;
    }
}
//点菜记录类:保存订单上的一道菜品记录
class Record {
    Record(){
    } //空构造器
    Record(int orderNum,String dishName,int portion,int num) { //构造器
        this.orderNum = orderNum;
        this.portion = portion;
        this.d = new Dish(dishName);
        this.num = num;
        setDish(dishName);
    }  //非空构造器
    int orderNum;//序号
    Dish d;//菜品
    public void setDish(String dishName) {
        d = new Dish(dishName);
    }
    int portion;//份额(1/2/3代表小/中/大份)
    int num; //份数,用来存储份数
    public int getPrice() {
        int Price = 0;
        Price = d.getPrice(portion)*num;
        return Price;
    }//计价,计算本条记录的价格,返回int单个菜品的总价
    //注意这里是未打折的总价
}

  而菜单计价程序5又与4不同,我就不多加赘述了。

其中考试的相关题目因为没有权限,依靠记忆也实在太扯,我相信大多数人应该跟我一样不想搞,我就偷一下懒。

(3)踩坑心得

要说踩坑我最觉得无语的地方还是期中考试的测试1,主要问题是测试点的精度问题,在Π的问题上我分别试了3.14,3.14159,3.1415926,因为我不知道Π该怎么打,所以用了笨办法,结果精度不够,3.1415926只能半对,要完成·测试点需要更高的精度。。。

测试2,3,4的话都没有什么坑人的地方,圆的精度问题也没那么离谱,在这就不详谈了。

说回菜单计价程序4,5,主要问题还是难,以及复杂,说多了都是泪。

(4)改进建议

改进建议还是一样,去学习自己没学会学懂的地方,以及多使用不同类对各功能进行区分,对之后修改代码更便利。有能力的可以画类图,看得懂,会用的话很好用。

(5)总结

这句话我每次都会说,一个课题学完了为什么不把标准示例给出来呢?留着过年嘛?菜单计价程序难度本来就高,一次落下了我都不知道之后怎么赶回来,还一个劲的加大难度,嫌我们si得不够彻底是吧。

posted @ 2023-06-30 14:52  wykxv  阅读(43)  评论(0)    收藏  举报