南航航空大学第二次BLOG

前言
这次从第一次题目难度开始,后面的数次难度激增,我也只有第一次全部写完pta的所有题目,后面就没有拿到过满分。但总体来说,主要知识点还是在设计类和学习java语言,以及用面向对象的思维方式。Java面向对象比c++更模块化,思维方式也不一样。对只接触过一点java语言的我们还是很有挑战的。还有一次期中考试,虽然难度不算大,但考察的内容很全面。
设计与分析
1.菜单计价程序-3
题目要求如下:
设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu {

Dish[] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

点菜记录类:保存订单上的一道菜品记录

Record {

int orderNum;//序号\

Dish d;//菜品\

int portion;//份额(1/2/3代表小/中/大份)\

int getPrice()//计价,计算本条记录的价格\

}

订单类:保存用户点的所有菜的信息。

Order {

Record[] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

输入格式:

桌号标识格式: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+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。
复杂度分析


类图

个人认为这是菜单系列的开端,后面的4和5都是在这一次的基础上进行的修改,并且这次的难度相对简单,代码结构相对清晰,在写的过程中没有遇到特别棘手的问题。
代码如下:

点击查看代码
import java.util.Scanner;
import java.util.Calendar;

class Dish {
    String name;
    int unit_price;

    int getPrice(int portion) {
        int price = 0;
        if (portion == 1) {
            price = unit_price;
        } else if (portion == 2) {
            price = Math.round((float) (unit_price * 1.5));
        } else if (portion == 3) {
            price = (unit_price * 2);
        }
        return price;
    }
}

class Menu {
    Dish[] dishes = new Dish[10];
    int count = 0;

    Dish searchDish(String dishName) {
        Dish temp = null;
        for (int i = count - 1; i >= 0; i--) {
            if (dishName.equals(dishes[i].name)) {
                temp = dishes[i];
                break;
            }
        }
        if (temp == null) {
            System.out.println(dishName + " does not exist");
        }
        return temp;
    }

    Dish addDish(String dishName, int unit_price) {
        Dish dish = new Dish();
        dish.name = dishName;
        dish.unit_price = unit_price;
        count++;
        return dish;
    }
}

class Record {
    int orderNum;
    Dish dish = new Dish();
    int num = 0;
    int portion;

    int getPrice() {
        return dish.getPrice(portion) * num;
    }
}

class Order {
    Record[] records = new Record[10];
    int count = 0; // 订单数量

    void addRecord(int orderNum, String dishName, int portion, int num) {
        records[count] = new Record();
        records[count].dish.name = dishName;
        records[count].orderNum = orderNum;
        records[count].portion = portion;
        records[count].num = num;
        count++;
    }

    int deleteRecordByOrderNum(int orderNum) {
        if (orderNum > count || orderNum <= 0) {
            System.out.println("delete error;");
            return 0;
        } else {
            return records[orderNum - 1].getPrice();
        }
    }
}

class Table {
    int tableNum;
    String tableDtime;
    int year, month, day, week, hh, mm, ss;
    int sum = 0;
    Order order = new Order();

    float discount = -1;

    void getTotalPrice() {
        if (discount > 0) {
            sum = Math.round(sum * discount);
            System.out.println("table " + tableNum + ": " + sum);
        } else {
            System.out.println("table " + tableNum + " out of opening hours");
        }
    }

    void preProcess(String tableDtime) {
        this.tableDtime = tableDtime;
        processTime();
        applyDiscount();
    }

    void processTime() {
        String[] temp = tableDtime.split(" ");
        tableNum = Integer.parseInt(temp[1]);
        String[] temp1 = temp[2].split("/");
        String[] temp2 = temp[3].split("/");

        year = Integer.parseInt(temp1[0]);
        month = Integer.parseInt(temp1[1]);
        day = Integer.parseInt(temp1[2]);

        Calendar c = Calendar.getInstance();
        c.set(year, (month - 1), day);
        week = c.get(Calendar.DAY_OF_WEEK);
        if (week == 1)
            week = 7;
        else
            week--;

        hh = Integer.parseInt(temp2[0]);
        mm = Integer.parseInt(temp2[1]);
        ss = Integer.parseInt(temp2[2]);
    }

    void applyDiscount() {
        if (week >= 1 && week <= 5) {
            if (hh >= 17 && hh < 20)
                discount = 0.8F;
            else if (hh == 20 && mm < 30)
                discount = 0.8F;
            else if (hh == 20 && mm == 30 && ss == 0)
                discount = 0.8F;
            else if (hh >= 11 && hh <= 13 || hh == 10 && mm >= 30)
                discount = 0.6F;
            else if (hh == 14 && mm < 30)
                discount = 0.6F;
            else if (hh == 14 && mm == 30 && ss == 0)
                discount = 0.6F;
        } else {
            if (hh >= 10 && hh <= 20)
                discount = 1.0F;
            else if (hh == 9 && mm >= 30)
                discount = 1.0F;
            else if (hh == 21 && mm < 30 || hh == 21 && mm == 30 && ss == 0)
                discount = 1.0F;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Menu menu = new Menu();
        Table[] tables = new Table[10];
        int menuCount = 0; // 菜单数
        int orderCount = 0; // 订单数
        Dish tempDish;
        int tableNum = 0; // 桌号
        int count;
        String[] temp;
        int a1, a2, a3, a4, a5;

        while (true) {
            String st = sc.nextLine();
            temp = st.split(" ");
            if (st.equals("end"))
                break;
            count = temp.length;
            if (count == 2) {
                if (temp[1].equals("delete")) {
                    a1 = Integer.parseInt(temp[0]);
                    int c = tables[tableNum].order.deleteRecordByOrderNum(a1);
                    tables[tableNum].sum -= c;
                } else {
                    a2 = Integer.parseInt(temp[1]);
                    menu.dishes[menuCount] = menu.addDish(temp[0], a2);
                    menuCount++;
                }
            } else if (count == 4) {
                if (temp[0].equals("table")) {
                    tableNum++;
                    orderCount = 0;
                    tables[tableNum] = new Table();
                    tables[tableNum].preProcess(st);
                    System.out.println("table " + tableNum + ": ");
                } else {
                    a3 = Integer.parseInt(temp[0]);
                    a4 = Integer.parseInt(temp[2]);
                    a5 = Integer.parseInt(temp[3]);
                    tables[tableNum].order.addRecord(a3, temp[1], a4, a5);
                    tempDish = menu.searchDish(temp[1]);
                    if (tempDish != null) {
                        tables[tableNum].order.records[orderCount].dish = tempDish;
                        int a = tables[tableNum].order.records[orderCount].getPrice();
                        System.out.println(tables[tableNum].order.records[orderCount].orderNum + " " + tempDish.name + " " + a);
                        tables[tableNum].sum += a;
                    }
                    orderCount++;
                }
            } else if (count == 5) {
                a1 = Integer.parseInt(temp[1]);
                a2 = Integer.parseInt(temp[3]);
                a3 = Integer.parseInt(temp[4]);
                tables[tableNum].order.addRecord(a1, temp[2], a2, a3);
                tempDish = menu.searchDish(temp[2]);
                if (tempDish != null) {
                    tables[tableNum].order.records[orderCount].dish.unit_price = tempDish.unit_price;
                    int b = tables[tableNum].order.records[orderCount].getPrice();
                    System.out.println(temp[1] + " table " + tables[tableNum].tableNum + " pay for table " + temp[0] + " " + b);
                    tables[tableNum].sum += b;
                }
                orderCount++;
            }
        }

        for (int i = 1; i < tableNum + 1; i++) {
            tables[i].getTotalPrice();
        }
    }
}

2.菜单计价程序-4 题目要求如下 本次课题比菜单计价系列-3增加的异常情况:

1、菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish"

2、桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error"

3、同一桌菜名、份额相同的点菜记录要合并成一条进行计算,否则可能会出现四舍五入的误差。

4、重复删除,重复的删除记录输出"deduplication :"+序号。

5、代点菜时,桌号不存在,输出"Table number :"+被点菜桌号+" does not exist";本次作业不考虑两桌记录时间不匹配的情况。

6、菜谱信息中出现重复的菜品名,以最后一条记录为准。

7、如果有重复的桌号信息,如果两条信息的时间不在同一时间段,(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)以内算统一时段),此时输出结果按不同的记录分别计价。

8、重复的桌号信息如果两条信息的时间在同一时间段,此时输出结果时合并点菜记录统一计价。前提:两个的桌号信息的时间都在有效时间段以内。计算每一桌总价要先合并符合本条件的饭桌的点菜记录,统一计价输出。

9、份额超出范围(1、2、3)输出:序号+" portion out of range "+份额,份额不能超过1位,否则为非法格式,参照第13条输出。

10、份数超出范围,每桌不超过15份,超出范围输出:序号+" num out of range "+份数。份数必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

11、桌号超出范围[1,55]。输出:桌号 +" table num out of range",桌号必须为1位或多位数值,最高位不能为0,否则按非法格式参照第16条输出。

12、菜谱信息中菜价超出范围(区间(0,300)),输出:菜品名+" price out of range "+价格,菜价必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

13、时间输入有效但超出范围[2022.1.1-2023.12.31],输出:"not a valid time period"

14、一条点菜记录中若格式正确,但数据出现问题,如:菜名不存在、份额超出范围、份数超出范围,按记录中从左到右的次序优先级由高到低,输出时只提示优先级最高的那个错误。

15、每桌的点菜记录的序号必须按从小到大的顺序排列(可以不连续,也可以不从1开始),未按序排列序号的输出:"record serial number sequence error"。当前记录忽略。(代点菜信息的序号除外)

16、所有记录其它非法格式输入,统一输出"wrong format"

17、如果记录以“table”开头,对应记录的格式或者数据不符合桌号的要求,那一桌下面定义的所有信息无论正确或错误均忽略,不做处理。如果记录不是以“table”开头,比如“tab le 55 2023/3/2 12/00/00”,该条记录认为是错误记录,后面所有的信息并入上一桌一起计算。

本次作业比菜单计价系列-3增加的功能:

菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+基础价格+"T"

例如:麻婆豆腐 9 T

菜价的计算方法:

周一至周五 7折, 周末全价。

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

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

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

输入格式:
桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:
按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”+英文空格

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价
复杂度分析


类图

代码的主要功能是实现餐厅点餐系统的各种操作,包括添加菜品、点餐记录、订单,计算价格等。
具体分析如下:

  1. Dish类:表示菜品,包含菜品名称、是否是特色菜、单价等属性,以及计算菜品价格的方法。

  2. Menu类:表示菜单,包含一个菜品数组,保存所有菜品信息。有添加菜品和查找菜品的方法。

  3. Record类:表示点餐记录,包含订单序号、菜品、数量、份额等属性,以及计算价格的方法。还有一些用于检查输入数据是否合法的方法。

  4. Order类:表示订单,包含一个点餐记录数组,保存订单上的每一道菜品记录。有添加记录、删除记录和计算订单总价的方法。

  5. Table类:表示桌子,包含桌号、是否有效、点餐时间、订单总价等属性。有处理时间、计算折扣、检查是否需要合并计算等方法。

  6. Main类:主类,包含main方法,用于接收用户输入并进行相应的操作。通过Scanner类获取用户输入的指令,根据指令调用相应的方法进行处理。
    这一题难度较大,我是参考其他的代码写的,自己在做的时候没有理清逻辑,导致测试点很多无法通过,在研究了他人的代码后,多少理解了一点题目。值得注意的是,在筛选时用了正则表达式。
    代码如下:

点击查看代码
import java.util.Scanner;
import java.util.Calendar;
import java.time.YearMonth;
class Dish {
    String name;//菜品名称
    boolean isSpecial = false;//是不是特色菜
    int unit_price;    //单价
    boolean exist = true;
    //int num;

    int getPrice(int portion) {
        int peic = 0;
        if (portion == 1) {
            peic = unit_price ;
        } else if (portion == 2) {
            peic = Math.round((float) (unit_price * 1.5)) ;
        } else if (portion == 3) {
            peic = (unit_price * 2) ;
        }
        return peic;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
    }
}

class Menu {
    Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息
    int count = 0;
    Dish searthDish(String dishName){
        Dish temd = null;
        for(int i=count-1;i>=0;i--){
            if(dishName.equals(dishs[i].name)&&dishs[i].exist){
                temd = dishs[i];
                break;
            }
        }
        if(temd==null){
            System.out.println(dishName+" does not exist");
        }
        return temd;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    Dish addDish(String dishName,int unit_price){

        Dish dh = new Dish();
        dh.name = dishName;
        dh.unit_price = unit_price;
        count++;
        if(unit_price<1||unit_price>300) {
            dh.exist = false;
            System.out.println(dishName+" price out of range "+unit_price);
        }
        return dh;
    }//添加一道菜品信息
}

class Record {
    int orderNum;//序号\
    Dish d = new Dish();//菜品\
    int num = 0;
    int portion;//份额(1/2/3代表小/中/大份)\
    boolean noNeed = true;
    int exist = 1;
    float realdiscnt = 1;
    //int asum = 0;
    boolean isTaked = false;//是否是给别人点的
    int getPrice(){
        return Math.round(d.getPrice(portion)*num);
    }//计价,计算本条记录的价格\
    float Checkportion(float discnt){//数量输入检查,计算价格
        if(portion>3||portion<1) {
            System.out.println(orderNum + " portion out of range " + portion);
            exist = 0;
            noNeed = false;
        }else if(num<1||num>15) {
            System.out.println(orderNum + " num out of range" +" "+num);
            exist = 0;
            noNeed = false;
        }else{
            if(d.isSpecial)
                if(discnt==0.8F||discnt==0.6F)
                    realdiscnt = 0.7F;
            if(exist==1&&!isTaked) {
                System.out.println(orderNum + " " + d.name + " " + getPrice());
            }
        }
        return realdiscnt;
    }
    boolean Checkahead(){
        if(num<1||num>15) {
            return false;
        }else return portion <= 3 && portion >= 1;
    }
}

class Order {
    Record[] records = new Record[100];//保存订单上每一道的记录
    int count = 0;//订单数量

    int getTotalPrice(){
        int sum=0;
        for(int i=0;i<count;i++){
            if(records[i].exist==0)
                continue;
            sum=sum+records[i].getPrice();
        }
        return sum;
    }//计算订单的总价
    Record addARecord(int orderNum, String dishName, int portion, int num){
        boolean flag = true;
        for(int i=0;i<count;i++){//不能点份额一样的菜
            if (records[i].d.name.equals(dishName) && records[i].portion == portion) {
                flag = false;
                break;
            }
        }
        count++;
        records[count] = new Record();
        records[count].d.name = dishName;
        records[count].orderNum = orderNum;
        records[count].portion = portion;
        records[count].num = num;
        records[count].noNeed = flag;
        return records[count];
    }//添加一条菜品信息到订单中。
    Record TakeOdfor(int mynum,Table[] table, int AnotherNum, int orderNum, String dishName, int portion, int num){
        boolean flag = false;
        for(Table t : table) {
            if(t==null)
                continue;
            if (t.tableNum != mynum&&t.tableNum==AnotherNum) {
                flag = true;
                break;
            }
        }
        if(flag) {
            count++;
            records[count] = new Record();
            records[count].d.name = dishName;
            records[count].orderNum = orderNum;
            records[count].portion = portion;
            records[count].num = num;
            return records[count];
        }else{
            System.out.println("Table number :" + AnotherNum + " does not exist");
            return null;
        }

    }

    void delARecordByOrderNum(int orderNum){
        if(orderNum>count||orderNum<=0){
            System.out.println("delete error;");
        }else {
            if(records[orderNum-1].exist==0) {
                System.out.println("deduplication "+orderNum);
                return;
            }
            records[orderNum-1].exist = 0;
        }
    }//根据序号删除一条记录
}
class Table {
    int tableNum;
    boolean inputIsvalid = false;
    boolean istoSum = false;//判断是否要合并计算
    String tableDtime;
    int year,month,day,week,hh,mm,ss;
    int sum = 0;//一桌价格 ;
    int primesum = 0;
    Order odt = new Order();
    float discnt = -1;
    float rediscnt = 1;
    void Gettottalprice(){
        if(discnt>0){
            primesum = odt.getTotalPrice();
            if(primesum==0)
                sum=0;
            System.out.println("table " + tableNum + ": " +primesum+" "+sum);
        }
    }
    void AheadProcess(String tableDtime){
        this.tableDtime = tableDtime;
        processTime();
        discount();
    }


    void processTime(){//处理时间
        String[] temp = tableDtime.split(" ");
        tableNum = Integer.parseInt(temp[1]);
        String[] temp1 = temp[2].split("/");
        String[] temp2 = temp[3].split("/");

        year = Integer.parseInt(temp1[0]);
        month = Integer.parseInt(temp1[1]);
        day = Integer.parseInt(temp1[2]);

        Calendar c = Calendar.getInstance();
        c.set(year, (month-1), day);
        week = c.get(Calendar.DAY_OF_WEEK);
        if(week==1)
            week = 7;
        else
            week--;
        hh = Integer.parseInt(temp2[0]);
        mm = Integer.parseInt(temp2[1]);
        ss = Integer.parseInt(temp2[2]);

    }
    boolean DateisValid(){
        if(year<1000)
            return false;
        if(month<1||month>12)
            return false;
        YearMonth mytime = YearMonth.of(year,month);
        return mytime.isValidDay(day);
    }
    boolean Daterande(){
        boolean flag = year >= 2022 && year <= 2023;
        if(!flag){
            System.out.println("not a valid time period");
            inputIsvalid = false;
        }
        return flag;

    }
    void discount(){

        if(week>=1&&week<=5)
        {
            if(hh>=17&&hh<20)
                discnt=0.8F;
            else if(hh==20&&mm<30)
                discnt=0.8F;
            else if(hh==20&&mm==30&&ss==0)
                discnt=0.8F;
            else if(hh>=11&&hh<=13||hh==10&&mm>=30)
                discnt=0.6F;
            else if(hh==14&&mm<30)
                discnt=0.6F;
            else if(hh==14&&mm==30&&ss==0)
                discnt=0.6F;
        }
        else
        {
            if(hh>=10&&hh<=20)
                discnt= 1.0F;
            else if(hh==9&&mm>=30)
                discnt= 1.0F;
            else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
                discnt= 1.0F;
        }
    }
    boolean CheckSameTime(Table table){
        if(tableNum!=table.tableNum)
            return false;
        if(week==table.week&&week>=1&&week<=5){
            return discnt == table.discnt;
        }else if(week==table.week&&week==6||week==7){
            int subtime = hh*3600+mm*60+ss-table.hh*3600-table.mm*60-ss;
            return Math.abs(subtime) < 3600;
        }
        return false;
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Menu mu = new Menu();
        Table[] tablemes = new Table[57];//桌号1-55;
        int j = 0;//菜单数
        int l = 0;//订单数
        //代点菜数
        //遍历桌
        int cntTab = 0;//桌号
        String[] temp;//字符串存储
        int tempordernum = 0;//临时存上一个有效序号
        String input;
        String regex = "[\\u4e00-\\u9fa5]* \\d*";//非特色菜菜谱
        String regex1 = "[\\u4e00-\\u9fa5]* \\d* T";//特色菜谱
        String regex2 = "\\d (delete)";//删除情况
        String regex3 = "(table) ([1-4][0-9]*|5[0-5]*) \\d{4}/\\d+/\\d{1,2} ([0-1]?[0-9]|2[0-3])/([0-5][0-9])/([0-5][0-9])";//添桌子的情况
        String regex4 = "([1-9]|[1-9][0-9]*) [\\u4e00-\\u9fa5]+ \\d+ \\d+";//点菜记录的添加;
        String regex5 = "([1-4][0-9]*|5[0-5]*|[1-9]) \\d [\\u4e00-\\u9fa5]+ [123] (1[0-5]|[1-9])";//代点菜
        while (true) {
            int count;//空格数量;
            input = sc.nextLine();//获取输入,每行
            if(input.equals("end"))
                break;
            if(input.isEmpty()) {
                System.out.println("wrong format");
                continue;
            }
            temp = input.split(" ");//分割
            /*
             * 判断输入的类型*/
            count = temp.length;
            if(count==2){//非特色菜菜谱,或者删除菜;
                if(input.matches(regex2)){//删除的情况桌子有效才删除
                    if (tablemes[cntTab] != null && tablemes[cntTab].inputIsvalid) {
                        tablemes[cntTab].odt.delARecordByOrderNum(Integer.parseInt(temp[0]));//删除

                    }
                }else if(input.matches(regex)){//非特色菜谱添加
                    if (cntTab == 0) {
                        mu.dishs[j] = new Dish();
                        mu.dishs[j] = mu.addDish(temp[0], Integer.parseInt(temp[1]));
                        j++;
                    } else if(tablemes[cntTab].inputIsvalid){
                        System.out.println("invalid dish");
                    }

                }else {
                    System.out.println("wrong format");
                }
            }else if(count==3){//特色菜菜谱
                if(input.matches(regex1)) {
                    if(cntTab!=0) {
                        if(tablemes[cntTab].inputIsvalid)
                            System.out.println("invalid dish");
                        else
                            continue;
                    }

                    mu.dishs[j] = new Dish();
                    mu.dishs[j] = mu.addDish(temp[0], Integer.parseInt(temp[1]));
                    mu.dishs[j].isSpecial = true;//是特色菜
                    j++;
                }else
                    System.out.println("wrong format");
            }
            //桌子的添加,点菜记录的添加,
            else if(temp[0].equals("table")||input.contains("/")) {
                cntTab++;
                tablemes[cntTab] = new Table();
                if(temp[0].equals("table")){
                    if(input.matches(regex3))
                        tablemes[cntTab].AheadProcess(input);
                    tablemes[cntTab].inputIsvalid=true;
                    if (input.matches(regex3)) {
                        if(tablemes[cntTab].inputIsvalid&&!tablemes[cntTab].DateisValid()){//检查日期
                            System.out.println(tablemes[cntTab].tableNum+" date error");
                            tablemes[cntTab].inputIsvalid=false;
                            continue;
                        }
                        if(tablemes[cntTab].inputIsvalid&&!tablemes[cntTab].Daterande()){
                            tablemes[cntTab].inputIsvalid=false;
                            continue;
                        }
                        for(int i =1;i<cntTab;i++){
                            if (tablemes[i].inputIsvalid && tablemes[cntTab].CheckSameTime(tablemes[i])) {//同一时间段
                                tablemes[cntTab].istoSum = true;
                            } else {
                                l = 0;
                            }
                            tempordernum = 0;
                        }
                        if(tablemes[cntTab].discnt>0)
                            System.out.println("table " + tablemes[cntTab].tableNum + ": ");
                        else {
                            System.out.println("table " + tablemes[cntTab].tableNum + " out of opening hours");
                            tablemes[cntTab].inputIsvalid = false;
                        }
                        continue;
                    } else {//第一个是table但不合法
                        tablemes[cntTab].inputIsvalid = false;
                        if(!temp[1].isEmpty() &&temp[1].charAt(0)>='1'&&temp[1].charAt(0)<='9'&&!temp[1].contains("/")){
                            if(Integer.parseInt(temp[1])<1||Integer.parseInt(temp[1])>55){
                                System.out.println(Integer.parseInt(temp[1])+" table num out of range");
                                continue;
                            }
                        }
                    }
                }
                System.out.println("wrong format");
                tablemes[cntTab].inputIsvalid = false;
                if(!temp[0].equals("table"))
                    tablemes[cntTab].istoSum = true;

            }else if(count==4){
                if (tablemes[cntTab] != null && input.matches(regex4) && (tablemes[cntTab].inputIsvalid || tablemes[cntTab].istoSum)) {//点菜记录
                    Dish tem;
                    int aheadcntTab = cntTab - 1;
                    if (!tablemes[cntTab].istoSum) {//不需要合并
                        tablemes[cntTab].odt.records[l] = new Record();
                        tablemes[cntTab].odt.records[l] = tablemes[cntTab].odt.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3]));
                        if (l - 1 >= 0) {//判断记录序号是否递增
                            tempordernum = getTempordernum(tablemes, l, cntTab, temp, tempordernum);
                        } else {//特殊情况
                            if (tablemes[cntTab].odt.records[l].Checkahead())
                                tempordernum = tablemes[cntTab].odt.records[l].orderNum;
                        }
                        if ((tem = mu.searthDish(temp[1])) != null) {
                            float temdiscnt;//临时储存折扣
                            tablemes[cntTab].odt.records[l].d = tem;
                            temdiscnt = tablemes[cntTab].odt.records[l].Checkportion(tablemes[cntTab].discnt);
                            if (temdiscnt != 1F)
                                tablemes[cntTab].rediscnt = temdiscnt;//最终折扣
                            if (tablemes[cntTab].odt.records[l].exist == 1 && tablemes[cntTab].odt.records[l].noNeed) {
                                if (tablemes[cntTab].rediscnt != 1) {
                                    tablemes[cntTab].sum += Math.round(tablemes[cntTab].odt.records[l].getPrice() * tablemes[cntTab].rediscnt);
                                    tablemes[cntTab].rediscnt = 1.0F;
                                } else
                                    tablemes[cntTab].sum += Math.round(tablemes[cntTab].odt.records[l].getPrice() * tablemes[cntTab].discnt);
                            }
                        }

                        if (!tablemes[cntTab].istoSum) {//如果份额名字未重复;
                            l++;
                        }
                    } else {//需要合并计算
                        tablemes[aheadcntTab].odt.records[l] = new Record();
                        tablemes[aheadcntTab].odt.records[l] = tablemes[aheadcntTab].odt.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3]));
                        if (l - 1 >= 0) {//判断记录序号是否递增
                            tempordernum = getTempordernum(tablemes, l, aheadcntTab, temp, tempordernum);
                        }
                        if ((tem = mu.searthDish(temp[1])) != null) {
                            float temdiscnt;//临时储存折扣
                            tablemes[aheadcntTab].odt.records[l].d = tem;
                            temdiscnt = tablemes[aheadcntTab].odt.records[l].Checkportion(tablemes[aheadcntTab].discnt);//计算折扣
                            if (temdiscnt == 0.7F)//如果需要调整
                                tablemes[aheadcntTab].rediscnt = temdiscnt;//最终折扣//更改折扣
                            if (tablemes[aheadcntTab].odt.records[l].exist == 1) {//必须存在
                                if (tablemes[aheadcntTab].rediscnt != 1) {
                                    tablemes[aheadcntTab].sum += Math.round(tablemes[aheadcntTab].odt.records[l].getPrice() * tablemes[aheadcntTab].rediscnt);
                                    tablemes[aheadcntTab].rediscnt = 1.0F;
                                } else
                                    tablemes[aheadcntTab].sum += Math.round(tablemes[aheadcntTab].odt.records[l].getPrice() * tablemes[cntTab].discnt) - 1;
                            }
                        }

                        l++;
                    }

                }
            }
            else if (tablemes[cntTab] != null && count == 5 && tablemes[cntTab].inputIsvalid) {//代点菜
                int temSum = 0;
                if (input.matches(regex5)) {
                    int AnothNum = Integer.parseInt(temp[0]);
                    tablemes[cntTab].odt.records[l] = tablemes[cntTab].odt.TakeOdfor(tablemes[cntTab].tableNum, tablemes, AnothNum, Integer.parseInt(temp[1]), temp[2], Integer.parseInt(temp[3]), Integer.parseInt(temp[4]));
                    Dish tem;
                    if ((tem = mu.searthDish(temp[2])) != null && tablemes[cntTab].odt.records[l] != null) {
                        tablemes[cntTab].odt.records[l].isTaked = true;//给别人diade
                        float temdiscnt;//临时储存折扣
                        tablemes[cntTab].odt.records[l].d = tem;
                        temdiscnt = tablemes[cntTab].odt.records[l].Checkportion(tablemes[cntTab].discnt);
                        if (temdiscnt != 1F)
                            tablemes[cntTab].rediscnt = temdiscnt;//最终折扣
                        if (tablemes[cntTab].odt.records[l].exist == 1 && tablemes[cntTab].odt.records[l].noNeed) {
                            if (tablemes[cntTab].rediscnt != 1) {
                                tablemes[cntTab].sum += Math.round((temSum = tablemes[cntTab].odt.records[l].getPrice()) * tablemes[cntTab].rediscnt);
                                tablemes[cntTab].rediscnt = 1.0F;
                            } else
                                tablemes[cntTab].sum += Math.round((temSum = tablemes[cntTab].odt.records[l].getPrice()) * tablemes[cntTab].discnt);
                        }
                        System.out.println(temp[1] + " table " + tablemes[cntTab].tableNum + " pay for table " + temp[0] + " " + temSum);
                    }
                    if (tablemes[cntTab].odt.records[l] != null)
                        l++;
                } else
                    System.out.println("wrong format");

            }
        }
        for(int i=1;i<=cntTab;i++){
            if(tablemes[i].inputIsvalid&&!tablemes[i].istoSum)
                tablemes[i].Gettottalprice();
        }

    }

    private static int getTempordernum(Table[] tablemes, int l, int cntTab, String[] temp, int tempordernum) {
        if (Integer.parseInt(temp[0]) <= tempordernum) {
            System.out.println("record serial number sequence error");
            tablemes[cntTab].odt.records[l].exist = 0;
        } else if (tablemes[cntTab].odt.records[l] != null && tablemes[cntTab].odt.records[l].noNeed)
            tempordernum = tablemes[cntTab].odt.records[l].orderNum;
        return tempordernum;
    }
}

3.菜单计价程序-5
题目要求如下
以上为菜单计价系列-3的题目要求,加粗的部分是有调整的内容。本次课题相比菜单计价系列-3新增要求如下:

1、菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+口味类型+英文空格+基础价格+"T"

例如:麻婆豆腐 川菜 9 T

菜价的计算方法:

周一至周五 7折, 周末全价。

特色菜的口味类型:川菜、晋菜、浙菜

川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣;

晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸;

浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜;

例如:麻婆豆腐 川菜 9 T

输入订单记录时如果是特色菜,添加口味度(辣/酸/甜度)值,格式为:序号+英文空格+菜名+英文空格+口味度值+英文空格+份额+英文空格+份数

例如:1 麻婆豆腐 4 1 9

单条信息在处理时,如果口味度超过正常范围,输出"spicy/acidity/sweetness num out of range : "+口味度值,spicy/acidity/sweetness(辣度/酸度/甜度)根据菜品类型择一输出,例如:

acidity num out of range : 5

输出一桌的信息时,按辣、酸、甜度的顺序依次输出本桌菜各种口味的口味度水平,如果没有某个类型的菜,对应的口味(辣/酸/甜)度不输出,只输出已点的菜的口味度。口味度水平由口味度平均值确定,口味度平均值只综合对应口味菜系的菜计算,不做所有菜的平均。比如,某桌菜点了3份川菜,辣度分别是1、3、5;还有4份晋菜,酸度分别是,1、1、2、2,辣度平均值为3、酸度平均值四舍五入为2,甜度没有,不输出。

一桌信息的输出格式:table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格+"川菜"+数量+辣度+英文空格+"晋菜"+数量+酸度+英文空格+"浙菜"+数量+甜度。

如果整桌菜没有特色菜,则只输出table的基本信息,格式如下,注意最后加一个英文空格:

table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格

例如:table 1: 60 36 川菜 2 爆辣 浙菜 1 微甜

计算口味度时要累计本桌各类菜系所有记录的口味度总和(每条记录的口味度乘以菜的份数),再除以对应菜系菜的总份数,最后四舍五入。

注:本题要考虑代点菜的情况,当前桌点的菜要加上被其他桌代点的菜综合计算口味度平均值。

2、考虑客户订多桌菜的情况,输入时桌号时,增加用户的信息:

格式:table+英文空格+桌号+英文空格+":"+英文空格+客户姓名+英文空格+手机号+日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

例如:table 1 : tom 13670008181 2023/5/1 21/30/00

约束条件:客户姓名不超过10个字符,手机号11位,前三位必须是180、181、189、133、135、136其中之一。

输出结果时,先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。不考虑各桌时间段的问题,同一个客户的所有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+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格

最后按拼音顺序输出每位客户(不考虑客户同名或拼音相同的情况)的支付金额,格式: 用户姓名+英文空格+手机号+英文空格+支付总金额,按输入顺序排列。
复杂度分析


类图

  1. 首先定义了一个Dish类,表示菜品。菜品有名称(name)、单价(unitPrice)和类型(type)属性。菜品类型使用枚举类DishType表示,包括川菜(Chuan)、晋菜(Jin)和浙菜(Zhe)。

  2. 然后定义了一个Menu类,表示菜单。菜单中可以添加菜品(addDish),并且可以根据菜品名称查找菜品(searchDish)。

  3. 接着定义了一个Record类,表示订单中的一条记录。记录包含订单号(orderNum)、菜品(dish)、份数(portion)、数量(quantity)、口味等级(level)、是否合法(flag)和赠送的桌号(givenId)等属性。记录还有计算价格的方法(getPrice)和打印信息的方法(print)。

  4. 然后定义了一个Table类,表示餐桌。餐桌有桌号(tableId)、客人姓名(name)、联系电话(phone)、就餐日期(date)、就餐时间(time)、是否合法(flag)等属性。餐桌可以根据就餐时间计算折扣系数(getCoefficient),计算总价(getTotalPrice)和应付金额(getCheckedPrice),获取平均口味等级(getAveLevel),添加订单记录(addRecord),删除订单记录(delRecordByOrderNum),打印餐桌信息(printId、printInfo)等。

  5. 最后在主函数中,通过Scanner类获取用户输入。创建菜单(menu)、餐桌(tables)和临时菜品(tempDish)等变量。根据用户输入的指令进行相应的操作,包括添加菜品、添加订单记录、删除订单记录等。最后输出每个餐桌的信息和客人的消费金额。
    菜单5依旧是在菜单3的基础上进行了修改,但是难度依旧不小,我也是参考了别人的代码,但还是没能完全达到题目的要求拿到满分。
    代码如下:

点击查看代码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
    public static void main(String[] args) throws ParseException {
        Menu menu = new Menu();
        // 读入菜单信息
        Scanner scanner = new Scanner(System.in);
        String menuLine = scanner.nextLine();
        while (!menuLine.startsWith("table")) {
            String[] menuInfo = menuLine.split(" ");
            if (menuInfo.length == 2) {
                String name = menuInfo[0];
                int unitPrice = Integer.parseInt(menuInfo[1]);
                if (menu.searchDish(name) == null) {
                    menu.addDish(name, unitPrice);
                }
            } else if (menuInfo.length == 4 && menuLine.endsWith("T")) {
                String name = menuInfo[0];
                String type = menuInfo[1];
                int unitPrice = Integer.parseInt(menuInfo[2]);
                Map<String, String> map = new HashMap<>() {
                    {
                        put("川菜", "Chuan");
                        put("晋菜", "Jin");
                        put("浙菜", "Zhe");
                    }
                };
                DishType dishType = DishType.valueOf(map.get(type));
                if (menu.searchDish(name) == null) {
                    menu.addDish(name, unitPrice, dishType);
                }
            } else {
                System.out.println("wrong format");
            }
            menuLine = scanner.nextLine();
        }
        ArrayList<Table> tables = new ArrayList<>();
        ArrayList<String> names = new ArrayList<>();
        // 读入订单信息
        int tableId = 0;
        String name;
        String phone;
        Date date;
        Date time;
        boolean legalTime = true;
        boolean legalFormat = true;
        String orderLine = menuLine;
        while (!orderLine.equals("end")) {
            String[] orderInfo = orderLine.split(" ");
            // 解析桌号标识
            if (orderLine.startsWith("table")) {
                legalFormat = true;
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
                SimpleDateFormat timeFormat = new SimpleDateFormat("HH/mm/ss");
                tableId = Integer.parseInt(orderInfo[1]);
                name = orderInfo[3];
                phone = orderInfo[4];
                try {
                    date = dateFormat.parse(orderInfo[5]);
                    time = timeFormat.parse(orderInfo[6]);
                } catch (Exception e) {
                    legalFormat = false;
                    System.out.println("wrong format");
                    orderLine = scanner.nextLine();
                    continue;
                }
                String regex = "^1(80|81|89|33|35|36)\\d{8}$";
                Table table = new Table(tableId, name, phone, date, time);
                tables.add(table);
                if (name.length() > 10 || !phone.matches(regex)) {
                    legalFormat = false;
                    System.out.println("wrong format");
                    orderLine = scanner.nextLine();
                    continue;
                }
                if (!names.contains(name)) {
                    names.add(name);
                }
                if (table.getCoefficient(true) == 0) {
                    legalTime = false;
                    System.out.println("table " + table.getTableId() + " out of opening hours");
                } else {
                    System.out.println(table.printId());
                }
            } else {
                if (legalFormat) {
                    int orderNum;
                    try {
                        orderNum = Integer.parseInt(orderInfo[0]);
                    } catch (Exception e) {
                        System.out.println("wrong format");
                        orderLine = scanner.nextLine();
                        continue;
                    }
                    if (orderLine.endsWith("delete")) {
                        if (!tables.get(tableId - 1).delRecordByOrderNum(orderNum)) {
                            System.out.println("delete error");
                        }
                    } else {
                        if (orderInfo.length == 4) {
                            String dishName = orderInfo[1];
                            int portion = Integer.parseInt(orderInfo[2]);
                            int quantity = Integer.parseInt(orderInfo[3]);
                            Dish dish = menu.searchDish(dishName);
                            if (dish == null) {
                                System.out.println(dishName + " does not exist");
                                orderLine = scanner.nextLine();
                                continue;
                            }
                            Record record = new Record(tableId, orderNum, dish, portion, quantity);
                            tables.get(tableId - 1).addRecord(record);
                            if (legalTime) {
                                System.out.println(record.print(tableId));
                            }
                        } else if (orderInfo.length == 5) {
                            String dishName = orderInfo[1];
                            int level = Integer.parseInt(orderInfo[2]);
                            int portion = Integer.parseInt(orderInfo[3]);
                            int quantity = Integer.parseInt(orderInfo[4]);
                            Dish dish = menu.searchDish(dishName);
                            if (dish == null) {
                                System.out.println(dishName + " does not exist");
                                orderLine = scanner.nextLine();
                                continue;
                            }
                            Record record = new Record(tableId, orderNum, dish, level, portion, quantity);
                            tables.get(tableId - 1).addRecord(record);
                            if (legalTime) {
                                System.out.println(record.print(tableId));
                            }
                        } else if (orderInfo.length == 6) {
                            int givenId = Integer.parseInt(orderInfo[1]);
                            String dishName = orderInfo[2];
                            int level = Integer.parseInt(orderInfo[3]);
                            int portion = Integer.parseInt(orderInfo[4]);
                            int quantity = Integer.parseInt(orderInfo[5]);
                            Dish dish = menu.searchDish(dishName);
                            if (dish == null) {
                                System.out.println(dishName + " does not exist");
                                orderLine = scanner.nextLine();
                                continue;
                            }
                            Record record1 = new Record(givenId, orderNum, dish, level, portion, quantity);
                            Record record2 = new Record(givenId, orderNum, dish, level, 0, quantity);
                            tables.get(tableId - 1).addRecord(record1);
                            tables.get(givenId - 1).addRecord(record2);
                            if (legalTime) {
                                System.out.println(record1.print(tableId));
                            }
                        } else {
                            System.out.println("wrong format");
                        }
                    }
                }
            }
            // 读入下一个桌号标识
            orderLine = scanner.nextLine();
        }
        scanner.close();
        for (Table table : tables) {
            if (table.isFlag() && table.getTotalPrice() != 0) {
                System.out.println(table.printInfo());
            }
        }
        names.sort(Comparator.naturalOrder());
        for (String customerName : names) {
            int sum = 0;
            String customerPhone = null;
            for (Table table : tables) {
                if (table.getName().equals(customerName)) {
                    sum += table.getCheckedPrice();
                    customerPhone = table.getPhone();
                }
            }
            if (sum != 0) {
                System.out.println(customerName + " " + customerPhone + " " + Math.round(sum));
            }
        }
    }
}
enum DishType {
    Chuan,
    Jin,
    Zhe,
}
class Dish {
    private final String name;
    private final int unitPrice;
    private DishType type;
    public Dish(String name, int unitPrice, DishType type) {
        this.name = name;
        this.unitPrice = unitPrice;
        this.type = type;
    }
    public Dish(String name, int unitPrice) {
        this.name = name;
        this.unitPrice = unitPrice;
    }
    @Override
    public String toString() {
        return name;
    }
    public Object getName() {
        return name;
    }
    public DishType getType() {
        return type;
    }
    public int getUnitPrice() {
        return unitPrice;
    }
}
class Menu {
    private final ArrayList<Dish> dishes = new ArrayList<>();
    public Dish searchDish(String dishName) {
        for (Dish dish : dishes) {
            if (dish.getName().equals(dishName)) {
                return dish;
            }
        }
        return null;
    }
    public void addDish(String dishName, int unitPrice) {
        dishes.add(new Dish(dishName, unitPrice));
    }
    public void addDish(String dishName, int unitPrice, DishType type) {
        dishes.add(new Dish(dishName, unitPrice, type));
    }
}
class Record {
    private final int orderNum;
    private final Dish dish;
    private final int portion;
    private final int quantity;
    private final int level;
    private final boolean flag;
    private final int givenId;
    public Record(int givenId, int orderNum, Dish dish, int portion, int quantity) {
        this.orderNum = orderNum;
        this.dish = dish;
        this.portion = portion;
        this.quantity = quantity;
        this.level = -1;
        this.flag = true;
        this.givenId = givenId;
    }
    public Record(int givenId, int orderNum, Dish dish, int level, int portion, int quantity) {
        this.orderNum = orderNum;
        this.dish = dish;
        this.portion = portion;
        this.quantity = quantity;
        this.level = level;
        this.flag = checkLevel();
        this.givenId = givenId;
    }
    private boolean checkLevel() {
        switch (dish.getType()) {
            case Chuan:
                return level <= 5 && level >= 0;
            case Jin:
                return level <= 4 && level >= 0;
            case Zhe:
                return level <= 3 && level >= 0;
            default:
                return true;
        }
    }
    public double getPrice() {
        if (!flag)
            return 0;
        double coefficient = 0;
        switch (portion) {
            case 1:
                coefficient = 1;
                break;
            case 2:
                coefficient = 1.5;
                break;
            case 3:
                coefficient = 2;
                break;
        }
        return Math.round(dish.getUnitPrice() * coefficient) * quantity;
    }
    public int getCheckedPrice(double coefficient) {
        return (int) Math.round(getPrice() * coefficient);
    }
    public String print(int tableId) {
        if (!flag) {
            switch (dish.getType()) {
                case Chuan:
                    return "spicy num out of range :" + level;
                case Jin:
                    return "acidity num out of range :" + level;
                case Zhe:
                    return "sweetness num out of range :" + level;
                default:
                    return null;
            }
        } else {
            if (givenId == tableId) {
                return orderNum + " " + dish.toString() + " " + Math.round(getPrice());
            }
            return orderNum + " table " + tableId + " pay for table " + givenId + " " + Math.round(getPrice());
        }
    }
    @Override
    public String toString() {
        return "Record [orderNum=" + orderNum + ", dish=" + dish + ", portion=" + portion + ", quantity=" + quantity
                + ", level=" + level + ", flag=" + flag + ", givenId=" + givenId + "]";
    }
    public int getLevel() {
        return level;
    }
    public Dish getDish() {
        return dish;
    }
    public boolean isFlag() {
        return flag;
    }
    public int getGivenId() {
        return givenId;
    }
    public int getQuantity() {
        return quantity;
    }
    public int getOrderNum() {
        return orderNum;
    }
}
class Table {
    private final ArrayList<Record> records = new ArrayList<>();
    private final int tableId;
    private final String name;
    private final String phone;
    private final Date date;
    private final Date time;
    private boolean flag;
    public Table(int tableId, String name, String phone, Date date, Date time) {
        this.name = name;
        this.phone = phone;
        this.date = date;
        this.time = time;
        this.tableId = tableId;
        this.flag = true;
    }
    public double getCoefficient(boolean special) throws ParseException {
        double coefficient = 0;
        SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm");
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        // 营业时间
        if (dayOfWeek == 1 || dayOfWeek == 7) {
            if (time.after(sdfTime.parse("9:29")) && time.before(sdfTime.parse("21:31"))) {
                coefficient = 1;
            }
        } else {
            if (time.after(sdfTime.parse("16:59")) && time.before(sdfTime.parse("20:31"))) {
                if (special) {
                    coefficient = 0.7;
                } else {
                    coefficient = 0.8;
                }
            } else if (time.after(sdfTime.parse("10:29")) && time.before(sdfTime.parse("14:31"))) {
                if (special) {
                    coefficient = 0.7;
                } else {
                    coefficient = 0.6;
                }
            }
        }
        if (coefficient == 0) {
            flag = false;
        }
        return coefficient;
    }
    public int getTotalPrice() {
        int sum = 0;
        for (Record record : records) {
            sum += (int) record.getPrice();
        }
        return sum;
    }
    public int getCheckedPrice() throws ParseException {
        int sum = 0;
        for (Record record : records) {
            if (record.getLevel() != -1) {
                sum += record.getCheckedPrice(getCoefficient(true));
            } else {
                sum += record.getCheckedPrice(getCoefficient(false));
            }
        }
        return sum;
    }
    public String getAveLevel(DishType type) {
        String[] spicy = {"不辣", "微辣", "稍辣", "辣", "很辣", "爆辣"};
        String[] acidity = {"不酸", "微酸", "稍酸", "酸", "很酸"};
        String[] sweetness = {"不甜", "微甜", "稍甜", "甜"};
        double sum = 0;
        double num = 0;
        for (Record record : records) {
            if (record.getDish().getType() == type) {
                if (record.isFlag() && tableId == record.getGivenId()) {
                    num += record.getQuantity();
                    sum += record.getLevel() * record.getQuantity();
                }
            }
        }
        if (num == 0) {
            return "";
        }
        int ave = (int) Math.round(sum / num);
        switch (type) {
            case Chuan:
                return " 川菜 " + (int) num + " " + spicy[ave];
            case Jin:
                return " 晋菜 " + (int) num + " " + acidity[ave];
            case Zhe:
                return " 浙菜 " + (int) num + " " + sweetness[ave];
            default:
                return null;
        }
    }
    public void addRecord(Record record) {
        records.add(record);
    }
    public boolean delRecordByOrderNum(int orderNum) {
        return records.removeIf(record -> record.getOrderNum() == orderNum);
    }
    public String printId() {
        return "table " + tableId + ": ";
    }
    public String printInfo() throws ParseException {
        String chuan = getAveLevel(DishType.Chuan);
        String jin = getAveLevel(DishType.Jin);
        String zhe = getAveLevel(DishType.Zhe);
        if (chuan.isEmpty() && jin.isEmpty() && zhe.isEmpty()) {
            return "table " + tableId + ": " + getTotalPrice() + " " + getCheckedPrice() + " ";
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append("table ").append(tableId).append(": ").append(getTotalPrice()).append(" ").append(getCheckedPrice());
            if (!chuan.isEmpty()) {
                sb.append(chuan);
            }
            if (!jin.isEmpty()) {
                sb.append(jin);
            }
            if (!zhe.isEmpty()) {
                sb.append(zhe);
            }
            return sb.toString();
        }
    }
    public boolean isFlag() {
        return flag;
    }
    public int getTableId() {
        return tableId;
    }
    public Object getName() {
        return name;
    }
    public String getPhone() {
        return phone;
    }
}
4.期中考试 7-3 测验3-继承与多态 这次期中考试的编程题难度还是正常的,还是在可以做出的范围内,只要跟着题目的要求的给出的类图就可以很顺利的完成代码,但最后因为时间问题还是没有拿到满分,在第三题测验3-继承与多态里还是有一个扣分点

代码如下:

点击查看代码
import java.util.Scanner;

abstract class Shape {
    public abstract double getArea();
}

class Circle extends Shape {
    
    private double radius;
    Circle(){
    }
    public Circle(double radius) {
        this.radius = radius;
    }
    public void setRadius(double radius){
        this.radius = radius;
    }
    public double getRadius(){
        return this.radius;
    }
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    private Point topLeftPoint;
    private Point lowerRightPoint;

    Rectangle(Point topLeftPoint, Point lowerRightPoint) {
        this.topLeftPoint = topLeftPoint;
        this.lowerRightPoint = lowerRightPoint;
    }
    public Point getTopLeftPoint(){
        return this.topLeftPoint;
    }
    public void setTopLeftPoint(Point topLeftPoint){
        this.topLeftPoint = topLeftPoint;
    }
    public Point getLowerRightPoint(){
        return this.lowerRightPoint;
    }
    public void setLowerRightPoint(Point lowerRightPoint){
        this.lowerRightPoint = lowerRightPoint;
    }
    public double getLength() {
        return Math.abs(topLeftPoint.getX() - lowerRightPoint.getX());
    }

    public double getHeight() {
        return Math.abs(topLeftPoint.getY() - lowerRightPoint.getY());
    }

    public double getArea() {
        double length = getLength();
        double height = getHeight();
        return length * height;
    }
}

class Point {
    private double x;
    private double y;

    Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {
        return x;
    }
    public void setX(double x){
        this.x = x;
    }
    public double getY() {
        return y;
    }
    public void setY(double y){
        this.y = y;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int choice = input.nextInt();
        switch (choice) {
            case 1: // Circle
                double radius = input.nextDouble();
                Shape circle = new Circle(radius);
                printArea(circle);
                break;
            case 2: // Rectangle
                double x1 = input.nextDouble();
                double y1 = input.nextDouble();
                double x2 = input.nextDouble();
                double y2 = input.nextDouble();
                Point leftTopPoint = new Point(x1, y1);
                Point lowerRightPoint = new Point(x2, y2);
                Shape rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
                printArea(rectangle);
                break;
        }
    }

    public static void printArea(Shape shape) {
        double area = shape.getArea();
        System.out.printf("%.2f\n", area);
    }
}
7-4 测验4-抽象类与接口

第四题因为测试点的不同我反而能拿到满分

代码如下:

点击查看代码
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;

interface Comparable {
    int compareTo(Shape shape);
}

abstract class Shape implements Comparable, java.lang.Comparable<Shape> {
    public abstract double getArea();

    public int compareTo(Shape shape) {
        double area1 = this.getArea();
        double area2 = shape.getArea();
        if (area1 < area2) {
            return -1;
        } else if (area1 > area2) {
            return 1;
        } else {
            return 0;
        }
    }
}

class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    public double getArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    private Point topLeftPoint;
    private Point lowerRightPoint;

    Rectangle(Point topLeftPoint, Point lowerRightPoint) {
        this.topLeftPoint = topLeftPoint;
        this.lowerRightPoint = lowerRightPoint;
    }

    public double getLength() {
        return Math.abs(topLeftPoint.getX() - lowerRightPoint.getX());
    }

    public double getHeight() {
        return Math.abs(topLeftPoint.getY() - lowerRightPoint.getY());
    }

    public double getArea() {
        double length = getLength();
        double height = getHeight();
        return length * height;
    }
}

class Point {
    private double x;
    private double y;

    Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        ArrayList<Shape> list = new ArrayList<>();
        int choice = input.nextInt();
        while (choice != 0) {
            switch (choice) {
                case 1: // Circle
                    double radius = input.nextDouble();
                    Shape circle = new Circle(radius);
                    list.add(circle);
                    break;
                case 2: // Rectangle
                    double x1 = input.nextDouble();
                    double y1 = input.nextDouble();
                    double x2 = input.nextDouble();
                    double y2 = input.nextDouble();
                    Point leftTopPoint = new Point(x1, y1);
                    Point lowerRightPoint = new Point(x2, y2);
                    Shape rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
                    list.add(rectangle);
                    break;
            }
            choice = input.nextInt();
        }
        list.sort(Comparator.<Shape>naturalOrder()); // 正向排序
        for (int i = 0; i < list.size(); i++) {
            System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
        }
    }
}

踩坑心得
经过这一阶段的学习与实践,我总结出了如下的问题

  1. 代码结构较为复杂,类的嵌套较多,可读性较差。
  2. 部分代码重复,可以进行优化和简化。
  3. 没有使用面向对象的设计原则,如封装、继承、多态等,代码可维护性较差。
    改进建议
  4. 优化代码结构,将每个类的功能和职责分离开来,提高代码的可读性和可维护性。
  5. 使用面向对象的设计原则,如封装、继承、多态等,提高代码的可维护性和扩展性。
  6. 优化代码逻辑,避免重复的代码,提高代码的效率和简洁性。
    总结
    相比于上一阶段的学习,我的能力有了一定的提升,经验也更加丰富了,但还是存在许多不足,比如还是不能在写代码前合理运用类图来完成代码,希望我在下一个阶段的学习中学会应用。
posted @ 2023-11-19 00:54  Mr_DNO  阅读(40)  评论(0)    收藏  举报