blog-2

PTA 4-6作业总结

作业总结

这三次作业都是与菜单类的有关,都是在菜单上对其进行改进和完善。涉及到的知识点主要就是对Java库函数的使用以及对类的创建和应用。题目每次都有一个题题量不多但是难度较大,个人认为这几次的作业难度都比较大,因为我没有一个满分,每次都有几个测试点过不去,并且自己也找不出来哪里有错误,只能被迫结束。但是这几次作业让我对Java的理解更加深刻,运用起来也更加的熟练。

二、设计与分析

2.1、菜单计价程序-2

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

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

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

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


订单分:点菜记录和删除信息。每一类信息都可包含一条或多条记录,每条记录一行。
点菜记录包含:序号、菜名、份额、份数。
份额可选项包括:1、2、3,分别代表小、中、大份。

删除记录格式:序号 delete

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

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

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

Dish {

String name;//菜品名称

int unit_price; //单价

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

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

Menu { Dish[] dishs ;//菜品数组,保存所有菜品信息 Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 Dish addDish(String dishName,int unit_price)//添加一道菜品信息}

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

Record { int orderNum;//序号\ Dish d;//菜品\ int portion;//份额(1/2/3代表小/中/大份)\ int getPrice()//计价,计算本条记录的价格\}

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

Order {

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

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

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

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

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

}

输入格式:

菜品记录格式:

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

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

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

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


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

输出格式:

按顺序输出每条订单记录的处理信息,

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

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

最后输出订单上所有菜品的总价(整数数值),

本次题目不考虑其他错误情况,如:菜单订单顺序颠倒、不符合格式的输入、序号重复等。

源代码

import java.util.Iterator;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
class Dish {
        String name;//菜品名称
        int unit_price;//单价
        public Dish(String name,int unit_price){
                this.name = name;
                this.unit_price = unit_price;
        }

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

        }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
        public String getName(){
                return name;
        }
}
class Menu {
        List<Dish> dishs=new ArrayList<>();//菜品数组,保存所有菜品信息
        Dish searthDish(String dishName){
                for(Dish dish:dishs){
                        if(dish.name.equals(dishName)){
                                return dish;
                        }
                }
                return null;
        }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
        public void addDish(String dishName,int unit_price){
                if(searthDish(dishName)==null){
                        Dish newname = new Dish(dishName,unit_price);
                        dishs.add(newname);
                }else{
                        searthDish(dishName).unit_price = unit_price;
                }
        }//添加一道菜品信息
}
class Record {
        int orderNum;//序号\
        Dish d;//菜品\
        int portion;//份额(1/2/3代表小/中/大份)
        int num;//表示份数
        public Record(int orderNum,Dish d,int portion,int num){
                this.orderNum = orderNum;
                this.d = d;
                this.portion = portion;
                this.num = num;
        }
        int getPrice(){
                return d.getPrice(portion)*num;
        }//计价,计算本条记录的价格\
}
class Order {
        List<Record> records = new ArrayList<>();//保存订单上每一道的记录
        public int getTotalPrice(){
                int total = 0;
                for(Record record:records){
                        total += record.getPrice();
                }
                return total;
        }//计算订单的总价
        public void addARecord(int orderNum,Dish dish,int portion,int num){
                Record newrecord = new Record(orderNum,dish,portion,num);
                records.add(newrecord);

                System.out.println(orderNum+" "+dish.getName()+" "+newrecord.getPrice());
                //return  newrecord;
        }//添加一条菜品信息到订单中。
       public boolean delARecordByOrderNum(int orderNum){
               Iterator<Record> iterator = records.iterator();
               while (iterator.hasNext()) {
                       Record record = iterator.next();
                       if (record.orderNum == orderNum) {
                               iterator.remove();
                               return true;
                       }
               }
               return false;
        }//根据序号删除一条记录
}
public class Main {
        public static void main(String[] args){
                Scanner input = new Scanner(System.in);
                Menu menu = new Menu();
                Order order = new Order();
                String inputmenu = input.nextLine();
                while (!inputmenu.equals("end")){
                        String[] inputmenus = inputmenu.split(" ");
                        if(inputmenus.length==2&&inputmenus[1].matches("\\d+")) {
                                menu.addDish(inputmenus[0], Integer.parseInt(inputmenus[1]));
                        }
                        if (inputmenus.length == 4) {
                                Dish dish = menu.searthDish(inputmenus[1]);
                                if(dish!=null) {
                                        order.addARecord(Integer.parseInt(inputmenus[0]), dish, Integer.parseInt(inputmenus[2]), Integer.parseInt(inputmenus[3]));
                                }
                                else
                                        System.out.println(inputmenus[1]+" "+"does not exist");
                        }
                        if(inputmenus.length==2&&inputmenus[0].matches("\\d")){
                                if(!order.delARecordByOrderNum(Integer.parseInt(inputmenus[0]))){
                                        System.out.println("delete error;");
                                }
                        }
                        inputmenu = input.nextLine();
                }
                System.out.println(order.getTotalPrice());
        }
}

 

 

类图:

复杂度:

分析:

系统包含3个类:Dish(菜品类),Menu(菜单类)和Order(订单类)。

Dish类有两个属性:name(菜品名称)和unit_price(菜品单价),和一个计算菜品价格的方法getPrice()。该方法根据输入的份额(1/2/3)计算出菜品的价格。

Menu类维护了一个dishs列表,保存所有菜品的信息。它提供了根据菜名在菜谱中查找菜品信息的方法searthDish()和添加一道菜品信息的方法addDish()。

Order类维护了一个records列表,保存订单上每一道菜品的记录。它提供了计算订单总价的方法getTotalPrice()和添加一条菜品信息到订单的方法addARecord()。

在Main类的main方法中,首先创建了菜单对象menu和订单对象order。然后通过输入命令的方式来操作菜单和订单。命令包括添加菜品信息、点菜和删除菜品记录。输入命令以"end"结束。

系统会根据输入的命令执行相应的操作,并在最后输出订单的总价。

 

 

分析:

在学生类中,定义了学号(number)、姓名(name)、语文成绩(chinese)、数学成绩(math)、物理成绩(physics)、总分(sum)和平均分(average)等属性。同时,提供了相应的构造方法和获取/设置属性的方法。

 

在学生类中还有一个名为"Print"的方法,用于打印学生的信息。

 

在主类Main中,首先创建了一个大小为5的学生数组array,并通过循环逐个初始化数组中的学生对象。初始化过程包括输入学号、姓名、语文成绩、数学成绩和物理成绩,并计算总分和平均分,然后设置给学生对象的属性。

 

最后,通过调用学生数组中任意一个学生对象的Print方法,打印所有学生的初始信息。

2.2、菜单计价程序-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+英文空格+桌号+“:”+英文空格+当前桌的总价

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

源码:

import java.util.Iterator;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.time.LocalTime;
class Dish {
    String name;//菜品名称
    int unit_price;//单价
    public Dish(String name,int unit_price){
        this.name = name;
        this.unit_price = unit_price;
    }

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

    }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
    public String getName(){
        return name;
    }
}
class Menu {
    List<Dish> dishs=new ArrayList<>();//菜品数组,保存所有菜品信息
    Dish searthDish(String dishName){
        for(Dish dish:dishs){
            if(dish.name.equals(dishName)){
                return dish;
            }
        }
        return null;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    public void addDish(String dishName,int unit_price){
        if(searthDish(dishName)==null){
            Dish newname = new Dish(dishName,unit_price);
            dishs.add(newname);
        }else{
            searthDish(dishName).unit_price = unit_price;
        }
    }//添加一道菜品信息
}
class Record {
    int orderNum;//序号\
    Dish d;//菜品\
    int portion;//份额(1/2/3代表小/中/大份)
    int num;//表示份数
    public Record(int orderNum,Dish d,int portion,int num){
        this.orderNum = orderNum;
        this.d = d;
        this.portion = portion;
        this.num = num;
    }
    int getPrice(){
        return d.getPrice(portion)*num;
    }//计价,计算本条记录的价格\
}
class Order {
    List<Record> records;//保存订单上每一道的记录
    int tablenum;
    String time;
    String hour;
    public Order(int tablenum,String time,String hour) {
        this.tablenum = tablenum;
        this.time = time;
        this.hour = hour;
        this.records = new ArrayList<>();
    }
    public int getTotalPrice(){
        int total = 0;
        for(Record record:records){
            total += record.getPrice();
        }
        return total;
    }//计算订单的总价
    public void addARecord(int orderNum,Dish dish,int portion,int num){
        Record newrecord = new Record(orderNum,dish,portion,num);
        records.add(newrecord);
        System.out.println(orderNum+" "+dish.getName()+" "+newrecord.getPrice());
    }//添加一条菜品信息到订单中。
    public void addARecords(int tablenum1,int tablenum2,int orderNum,Dish dish,int portion,int num){
        Record newrecord = new Record(orderNum,dish,portion,num);
        records.add(newrecord);
        System.out.println(orderNum+" table "+tablenum1+" pay for table "+ tablenum2 +" "+newrecord.getPrice());
    }//添加一条菜品信息到订单中。
    public boolean delARecordByOrderNum(int orderNum){
        Iterator<Record> iterator = records.iterator();
        while (iterator.hasNext()) {
            Record record = iterator.next();
            if (record.orderNum == orderNum) {
                iterator.remove();
                return true;
            }
        }
        return false;
    }//根据序号删除一条记录
}
class Table{
    List<Order> tables;
    public Table(){
        this.tables = new ArrayList<>();
    }
    public void addtable(int tablenum,String time,String hour) {
            Order newtable = new Order(tablenum, time, hour);
            tables.add(newtable);
    }
    public int timeround(String yeartime){
        String[] time = yeartime.split("/");
        int[] times = new int[3];
        times[0] = Integer.parseInt(time[0]);
        times[1] = Integer.parseInt(time[1]);
        times[2] = Integer.parseInt(time[2]);
        Calendar Monthday = new GregorianCalendar(times[0], times[1] - 1, times[2]);
        int weekday = Monthday.get(Calendar.DAY_OF_WEEK) - 1;
        if (weekday == 0) {
            weekday = 7; // 将周日(Calendar.SUNDAY)转换为7
            }
        if(1<=weekday&&weekday<=5){
            return 0;
            }
            else
                return 1;
    }
    public Order searchOrder(int tableNum){
        for(Order order : tables){
            if(order.tablenum == tableNum){
                return order;
            }
        }
        return null;
    }
    public int totalmey(String yeartime,String daytime,int total){
        String[] hour = daytime.split("/");
        //int[] hours = new int[3];
        int hours0 = Integer.parseInt(hour[0]);
        int hours1 = Integer.parseInt(hour[1]);
        int hours2 = Integer.parseInt(hour[2]);
        LocalTime t0 = LocalTime.of(hours0,hours1,hours2);
        LocalTime t1 = LocalTime.of(10,30,0);
        LocalTime t2 = LocalTime.of(14,30,0);
        LocalTime t3 = LocalTime.of(17,0,0);
        LocalTime t4 = LocalTime.of(20,30,0);
        LocalTime t5 = LocalTime.of(9,30,0);
        LocalTime t6 = LocalTime.of(21,30,0);
        if(timeround(yeartime)==0){
            if(t0.isAfter(t1)&&t0.isBefore(t2)||t0.equals(t1)||t0.equals(t2)){
                return (int)Math.round(total*0.6);
            }
            else if(t0.isAfter(t3)&&t0.isBefore(t4)||t0.equals(t3)||t0.equals(t4)){
                return (int)Math.round(total*0.8);
            }
            else {
                return 0;
            }
        }
        else if(timeround(yeartime)==1){
            if(t0.isAfter(t5)&&t0.isBefore(t6)||t0.equals(t5)||t0.equals(t6)){
                return total;
            }
            else {
                return 0;
            }
        }
        else
            return 0;
        }
}
public class Main {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        Menu menu = new Menu();
        Table table = new Table();
        String inputmenu = input.nextLine();
        int num=0;
        while (!inputmenu.equals("end")){
            String[] inputmenus = inputmenu.split(" ");
            if(inputmenus.length==2&&inputmenus[1].matches("\\d+")) {
                menu.addDish(inputmenus[0], Integer.parseInt(inputmenus[1]));
            }
            else if(inputmenus.length==4&&inputmenus[1].matches("\\d+")){//table
                num = Integer.parseInt(inputmenus[1]);
                System.out.println("table "+num+": ");
                table.addtable(num,inputmenus[2],inputmenus[3]);
            }
            else if (inputmenus.length == 4) {
                Dish dish = menu.searthDish(inputmenus[1]);
                if(dish!=null) {
                    table.searchOrder(num).addARecord(Integer.parseInt(inputmenus[0]), dish, Integer.parseInt(inputmenus[2]), Integer.parseInt(inputmenus[3]));
                }
                else
                    System.out.println(inputmenus[1]+" "+"does not exist");
            }
            else if(inputmenus.length==5){
                Dish dish = menu.searthDish(inputmenus[2]);
                if(dish!=null) {
                    table.searchOrder(num).addARecords(num,Integer.parseInt(inputmenus[0]),Integer.parseInt(inputmenus[1]), dish, Integer.parseInt(inputmenus[3]), Integer.parseInt(inputmenus[4]));
                }
                else
                    System.out.println(inputmenus[1]+" "+"does not exist");
            }
            else if(inputmenus.length==2&&inputmenus[0].matches("\\d")){
                if(!table.searchOrder(num).delARecordByOrderNum(Integer.parseInt(inputmenus[0]))){
                    System.out.println("delete error;");
                }
            }

            inputmenu = input.nextLine();
        }
        for(Order order : table.tables){
            if(table.totalmey(order.time,order.hour,order.getTotalPrice())==0){
                System.out.println("table "+order.tablenum+" out of opening hours");
            }
            else
            System.out.println("table "+order.tablenum+": "+table.totalmey(order.time,order.hour,order.getTotalPrice()));
        }
    }
}

 

类图:

复杂度:

分析:

Dish类表示菜品,有菜品名称和单价两个属性,还有一个 getPrice(int portion) 方法用于根据份额计算菜品价格。这个方法根据传入的份额参数计算出对应的价格,并返回。

Menu类表示菜单,包含一个菜品数组。它提供了两个方法,searthDish()和addDish()。searthDish()方法根据菜名在菜谱中查找菜品信息,并返回对应的 Dish 对象。addDish()方法用于添加一道菜品信息到菜单中。

Record类表示订单记录,包含序号、菜品、份额和份数等属性。它还提供了一个计算记录价格的方法 getPrice(),该方法内部调用菜品的 getPrice(int portion) 方法计算记录价格。

Order类表示订单,包含多个订单记录。它提供了计算总价的方法 getTotalPrice(),遍历订单上的每一道记录,调用记录的 getPrice() 方法计算价格,并累加到总价中。同时,它还提供了添加和删除订单记录的方法 addARecord() 和 delARecordByOrderNum()。

Table类表示桌子,包含一个订单列表。它提供了添加桌子的方法 addtable()、根据桌号查找订单的方法 searchOrder()、计算订单在不同时间段的优惠价格的方法 totalmey() 和计算当前时间所属时间段的方法 timeround()。

在Main类的main方法中,首先创建了菜单对象 menu 和桌子对象 table。然后通过输入命令的方式来操作菜单和订单。命令包括添加菜品信息、添加桌子、点菜、删除菜品记录。输入命令以 "end" 结束。

在输出订单总价之前,通过遍历 table.tables 列表来判断每一个订单在营业时间内的优惠价格,并输出每个桌子的总价。营业时间的判断通过调用 Table 类的 timeround() 方法完成。

总体来说,这段代码实现了一个简单的点餐系统,具有添加菜品、管理菜单、添加订单、删除订单等功能,并能根据营业时间计算订单的优惠价格

2.3、菜单计价程序-4

题目:

本体大部分内容与菜单计价程序-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)//根据序号查找一条记录

}

本次课题比菜单计价系列-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+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价

源代码:

import java.text.SimpleDateFormat;
import java.util.*;
import java.time.LocalTime;
class Dish {
    String name;//菜品名称
    int unit_price;//单价
    boolean Tname;
    public Dish(String name,int unit_price,boolean Tname){
        this.name = name;
        this.unit_price = unit_price;
        this.Tname = Tname;
    }
    public int getPrice(int portion){
        if(portion==1)
            return unit_price;
        else if(portion==2)
            return (int)Math.round(unit_price*1.5);
        else if(portion==3)
            return unit_price*2;
        else
            return 0;

    }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
    public String getName(){
        return name;
    }
}
class Menu {
    List<Dish> dishs=new ArrayList<>();//菜品数组,保存所有菜品信息
    Dish searthDish(String dishName){
        for(Dish dish:dishs){
            if(dish.name.equals(dishName)){
                return dish;
            }
        }
        return null;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    public void addDish(String dishName,int unit_price,boolean Tname){
        if(searthDish(dishName)==null){
            Dish newname = new Dish(dishName,unit_price,Tname);
            dishs.add(newname);
        }else{
            searthDish(dishName).unit_price = unit_price;
        }
    }//添加一道菜品信息
}
class Record {
    int orderNum;//序号\
    Dish d;//菜品\
    int portion;//份额(1/2/3代表小/中/大份)
    int num;//表示份数
    public Record(int orderNum,Dish d,int portion,int num){
        this.orderNum = orderNum;
        this.d = d;
        this.portion = portion;
        this.num = num;
    }
    int getPrice(){
        return d.getPrice(portion)*num;
    }//计价,计算本条记录的价格\
}
class Order {
    List<Record> records;//保存订单上每一道的记录
    int tablenum;
    String time;
    String hour;
    public Order(int tablenum,String time,String hour) {
        this.tablenum = tablenum;
        this.time = time;
        this.hour = hour;
        this.records = new ArrayList<>();
    }
    public int getTotalPrice(){
        int total = 0;
        for(Record record:records){
            total += record.getPrice();
        }
        return total;
    }//计算订单的总价
    public int getfinalprice(){
        double total = 0;
        for(Record record:records){
            if(record.d.Tname==false){
                total = total + record.getPrice()*0.6;
            }
            else
                total = total + record.getPrice()*0.7;
        }
        return (int)Math.round(total);
    } //周一到周五打完折后的总价
    public int getfinalprice1(){
        double total = 0;
        for(Record record:records){
            if(record.d.Tname==false){
                total = total + record.getPrice()*0.8;
            }
            else
                total = total + record.getPrice()*0.7;
        }
        return (int)Math.round(total);
    }//周六周日打完折后的总价
    public void addARecord(int orderNum,Dish dish,int portion,int num){
        Record newrecord = new Record(orderNum,dish,portion,num);
        records.add(newrecord);
        System.out.println(orderNum+" "+dish.getName()+" "+newrecord.getPrice());
    }//添加一条菜品信息到订单中。
    public void addARecords(int tablenum1,int tablenum2,int orderNum,Dish dish,int portion,int num){
        Record newrecord = new Record(orderNum,dish,portion,num);
        records.add(newrecord);
        System.out.println(orderNum+" table "+tablenum1+" pay for table "+ tablenum2 +" "+newrecord.getPrice());
    }//带点菜信息
    public boolean delARecordByOrderNum(int orderNum){         //删除点菜记录
        Iterator<Record> iterator = records.iterator();
        while (iterator.hasNext()) {
            Record record = iterator.next();
            if (record.orderNum == orderNum) {
                iterator.remove();
                return true;
            }
        }
        return false;
    }//根据序号删除一条记录
}
class Table{
    List<Order> tables;
    public Table(){
        this.tables = new ArrayList<>();
    }
    public void addtable(int tablenum,String time,String hour) {       //添加桌号信息
        Order newtable = new Order(tablenum, time, hour);
        tables.add(newtable);
    }
    public int timeround(String yeartime){                //判断星期几
        String[] time = yeartime.split("/");
        int[] times = new int[3];
        times[0] = Integer.parseInt(time[0]);
        times[1] = Integer.parseInt(time[1]);
        times[2] = Integer.parseInt(time[2]);
        Calendar Monthday = new GregorianCalendar(times[0], times[1] - 1, times[2]);
        int weekday = Monthday.get(Calendar.DAY_OF_WEEK) - 1;
        if (weekday == 0) {
            weekday = 7; // 将周日(Calendar.SUNDAY)转换为7
        }
        if(1<=weekday&&weekday<=5){
            return 0;
        }
        else
            return 1;
    }
    public Order searchOrder(int tableNum){           //遍历桌号
        for(Order order : tables){
            if(order!=null&&order.tablenum == tableNum){
                return order;
            }
        }
        return null;
    }
    public int searchOrdernum(int tableNum){           //遍历桌号
        for(Order order : tables){
            if(order.tablenum == tableNum){
                return order.tablenum;
            }
        }
        return 0;
    }
    public int totalmey(String yeartime,String daytime,int tablenum){        //时间
        String[] hour = daytime.split("/");
        int hours0 = Integer.parseInt(hour[0]);
        int hours1 = Integer.parseInt(hour[1]);
        int hours2 = Integer.parseInt(hour[2]);
        LocalTime t0 = LocalTime.of(hours0,hours1,hours2);
        LocalTime t1 = LocalTime.of(10,30,0);
        LocalTime t2 = LocalTime.of(14,30,0);
        LocalTime t3 = LocalTime.of(17,0,0);
        LocalTime t4 = LocalTime.of(20,30,0);
        LocalTime t5 = LocalTime.of(9,30,0);
        LocalTime t6 = LocalTime.of(21,30,0);
        if(timeround(yeartime)==0){
            if(t0.isAfter(t1)&&t0.isBefore(t2)||t0.equals(t1)||t0.equals(t2)){
                return 0;
            }
            else if(t0.isAfter(t3)&&t0.isBefore(t4)||t0.equals(t3)||t0.equals(t4)){
                return 1;
            }
            else {
                return -1;
            }
        }
        else if(timeround(yeartime)==1){
            if(t0.isAfter(t5)&&t0.isBefore(t6)||t0.equals(t5)||t0.equals(t6)){
                return 2;
            }
            else {
                return -1;
            }
        }
        else
            return -1;
    }
}

public class Main {
    static int[] month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Menu menu = new Menu();
        Table table = new Table();
        boolean ordering = true;
        String inputmenu = input.nextLine();
        String[] delete = new String[50];
        int[] menunum = new int[20];
        delete[0] = "0";
        int num = 0, i = 0,id = 0,n=0,bin = -1,j=0,c=0,v=0,t=0;
        boolean tired = true;
        boolean rice = true;
        boolean button = true;
        List<Integer> nums = new ArrayList<>();
        List<String> dates = new ArrayList<>();
        List<String> hours = new ArrayList<>();
        int q=0,w=0,e=0;
        while (!inputmenu.equals("end")) {
            String[] inputmenus = inputmenu.split("\\s");
            if(judgecontainspace(inputmenus,inputmenu)==0){
                if(inputmenu.startsWith(" ")){
                    System.out.println("wrong format");
                }
                else if(inputmenus.length==2&&inputmenus[0].matches("^[\\u4e00-\\u9fa5]+")){
                    System.out.println("wrong format");
                }
                else if(inputmenus[0].matches("table")){
                    ordering=false;
                    rice = false;
                    System.out.println("wrong format");
                }
                else if(inputmenus.length==4&&inputmenus[0].matches("\\d+")&&rice&&button){
                    System.out.println("wrong format");
                }
                else if(inputmenus[0].matches("\\d+")&&!button){

                }
                else if(inputmenu.isEmpty())
                    System.out.println("wrong format");
                else
                    System.out.println("wrong format");

            }
            else if (inputmenus.length == 2 && inputmenus[0].matches("^[\\u4e00-\\u9fa5]+") && inputmenus[1].matches("^\\d+$")) {//菜单
                if(ordering) {
                    if (judgemessage(inputmenus[1]) == 1 && 0 < Integer.parseInt(inputmenus[1]) && Integer.parseInt(inputmenus[1]) < 300) {
                        if (id == i) {
                            menu.addDish(inputmenus[0], Integer.parseInt(inputmenus[1]), false);
                        } else
                            System.out.println("invalid dish");             //点菜中混淆菜品信息
                        id++;
                    } else
                        System.out.println(inputmenus[0] + " price out of range " + inputmenus[1]);
                }
            }
            else if (inputmenus.length == 3 && inputmenus[0].matches("^[\\u4e00-\\u9fa5]+$") && inputmenus[1].matches("^\\d+$") && inputmenus[2].matches("T")) {//菜单特色菜
                if(ordering) {
                    if (v == 0) {
                        menu.addDish(inputmenus[0], Integer.parseInt(inputmenus[1]), true);
                        v++;
                        id++;
                    }//特色菜
                    else
                        System.out.println("invalid dish");
                }
            }
            else if (inputmenus[0].matches("table") && inputmenus[1].matches("^\\d+$") && judgedate(inputmenus[2])&&judgeday(inputmenus[3])&&judgedate1(inputmenus[2])&&judgeday1(inputmenus[3])) {//table   //桌号与时间
                if (judgeyear(inputmenus[2])) {
                    if (judgemessage(inputmenus[1]) == 1) {
                        if (0 < Integer.parseInt(inputmenus[1]) && Integer.parseInt(inputmenus[1]) < 56) {//添加桌号信息
                            if (table.totalmey(inputmenus[2], inputmenus[3], Integer.parseInt(inputmenus[1])) != -1) {
                                num = Integer.parseInt(inputmenus[1]);
                                nums.add(num);
                                dates.add(inputmenus[2]);
                                hours.add(inputmenus[3]);
                                System.out.println("table " + num + ": ");
                                table.addtable(num, inputmenus[2], inputmenus[3]);
                                ordering = true;
                                q++;
                            } else {
                                System.out.println("table " + inputmenus[1] + " out of opening hours");
                                ordering=false;
                            }

                        }
                        else {  //桌号超出范围
                            System.out.println(inputmenus[1] + " table num out of range");
                            ordering = false;
                        }

                    } else {
                        System.out.println("wrong format");
                        ordering = false;
                    }
                } else {
                    System.out.println("not a valid time period");
                    ordering = false;
                }
            }
            else if(inputmenus.length == 4 && inputmenus[0].matches("table") && inputmenus[1].matches( "[a-zA-Z]+")){
                System.out.println("wrong format");
                tired = false;
                ordering=false;
                button=false;
            }
            else if(inputmenus.length == 4 && inputmenus[0].matches("table") && inputmenus[1].matches("^\\d+$") &&( !judgedate1(inputmenus[2])||!judgeday1(inputmenus[3]))){
                System.out.println("wrong format");
                ordering=false;
            }
            else if(inputmenus.length == 4 && inputmenus[0].matches("table") && inputmenus[1].matches("^\\d+$") &&( !judgedate(inputmenus[2])||!judgeday(inputmenus[3]))){
                System.out.println(inputmenus[1]+" date error");
                ordering=false;
            }
            else if (inputmenus.length == 4 && inputmenus[0].matches("\\d+$") && inputmenus[1].matches("^[\\u4e00-\\u9fa5]+$") && inputmenus[2].matches("\\d+") && inputmenus[3].matches("\\d+")) {//点菜
                if(ordering) {
                    if (judgemessage(inputmenus[0]) == 1) {
                        Dish dish = menu.searthDish(inputmenus[1]);      //菜品是否存在
                        if (c == 0) {
                            c = table.searchOrdernum(num);
                        }
                        if(!dateinterval(nums, dates, hours)){
                            c = table.searchOrdernum(num);
                            Arrays.fill(menunum, 0);
                            j = 0;
                        }
                        else if (c != table.searchOrdernum(num)) {
                            c = table.searchOrdernum(num);
                            Arrays.fill(menunum, 0);
                            j = 0;
                        }
                        if (dish != null) {
                            if (Integer.parseInt(inputmenus[2]) > 3) {
                                System.out.println(Integer.parseInt(inputmenus[0]) + " portion out of range " + Integer.parseInt(inputmenus[2]));  //份额超出范围
                            } else if (Integer.parseInt(inputmenus[3]) > 15)
                                System.out.println(Integer.parseInt(inputmenus[0]) + " num out of range " + Integer.parseInt(inputmenus[3]));  //数量超出范围
                            else {
                                if (j == 0) {             //第一份添加进去
                                    menunum[j] = Integer.parseInt(inputmenus[0]);
                                    j++;
                                    table.searchOrder(num).addARecord(Integer.parseInt(inputmenus[0]), dish, Integer.parseInt(inputmenus[2]), Integer.parseInt(inputmenus[3]));
                                } else {
                                    if (judgemenu(menunum, Integer.parseInt(inputmenus[0]))) {
                                        table.searchOrder(num).addARecord(Integer.parseInt(inputmenus[0]), dish, Integer.parseInt(inputmenus[2]), Integer.parseInt(inputmenus[3]));
                                    } else {      //不是递增就输出
                                        System.out.println("record serial number sequence error");
                                    }
                                    menunum[j] = Integer.parseInt(inputmenus[0]);
                                    j++;
                                }

                            }
                        } else
                            System.out.println(inputmenus[1] + " " + "does not exist");
                    }
                    else
                        System.out.println("wrong format");
                }
            }
            else if (inputmenus.length == 5 && inputmenus[0].matches("\\d+") && inputmenus[1].matches("\\d+")) {          //代点菜信息
                Dish dish = menu.searthDish(inputmenus[2]);//菜品是否存在
                if(table.searchOrder(Integer.parseInt(inputmenus[0]))!=null&&table.searchOrder(Integer.parseInt(inputmenus[0])).tablenum!=num) {
                    if (dish != null) {
                        table.searchOrder(num).addARecords(num, Integer.parseInt(inputmenus[0]), Integer.parseInt(inputmenus[1]), dish, Integer.parseInt(inputmenus[3]), Integer.parseInt(inputmenus[4]));
                    } else
                        System.out.println(inputmenus[1] + " " + "does not exist");

                }
                else
                    System.out.println("Table number :"+inputmenus[0]+" does not exist");
            }
            else if (inputmenus.length == 2 && inputmenus[0].matches("\\d+")) {//删除菜品信息
                if (ordering) {
                    if(t!=table.searchOrdernum(num)){
                        for(int k=0;k<n+1;k++)
                            delete[k]="0";
                    }
                    ++n;
                    for (int m = 0; m < n; m++) {
                        if (delete[m].equals(inputmenus[0])) {
                            bin = 1;
                        } else
                            bin = 0;
                    }
                    if (bin == 1) {                //重复删除
                        System.out.println("deduplication " + inputmenus[0]);
                    } else if (!table.searchOrder(num).delARecordByOrderNum(Integer.parseInt(inputmenus[0]))) {  //删除
                        System.out.println("delete error;");
                    }
                    delete[n] = inputmenus[0];
                    t = table.searchOrdernum(num);
                    //System.out.println(t);
                }
            }
            else {
                if(tired) {
                    System.out.println("wrong format");
                }
            }
            i++;
            inputmenu = input.nextLine();
        }
        for (Order order : table.tables) {
            if(table!=null) {
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0)        //周一到周五中午
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice());
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1)           //周一到周五晚上
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1());
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2)        //周六周日
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice());
            }
        }
    }
    public static int judgecontainspace(String[] inputmenus,String inputmenu){
        if (inputmenu.startsWith(" ") || inputmenu.endsWith(" ")) {
            return 0;
        }
        else {
            for (String str : inputmenus) {
                if (str.isEmpty()) {
                    return 0;
                }
            }
        }
        return 1;
    }
    public static int judgemessage(String figure) {
        try {
            int num = Integer.parseInt(figure);
            if (figure.charAt(0) == '0') {
                return 0;
            }
            return 1;
        } catch (NumberFormatException e) {
            return 0;
        }
    }
    public static boolean judgemenu(int[] num,int shu){
        int max = -100;
        for(int i=0;i<10;i++){           //查找最大值
            if(num[i]>max){
                max = num[i];
            }
        }
        if(shu>max){        //是否有序
            return true;
        }
        return false;
    }
    public static int judgerun(int data) {
        if (data % 4 == 0 && data % 100 != 0 || data % 400 == 0) {
            return 1;
        } else
            return 0;
    }
    public static boolean judgedate(String date) {
        if(date.indexOf('/')==-1){
            return false;
        }
        else {
            String[] time = date.split("/");
            int date0 = Integer.parseInt(time[0]);
            int date1 = Integer.parseInt(time[1]);
            int date2 = Integer.parseInt(time[2]);
            if (time[0].length() == 4 && (time[1].length() == 1 || time[1].length() == 2) && 0 < date1 && date1 < 13 && (time[2].length() == 1 || time[2].length() == 2) && 0 < date2 && date2 < 32) {
                if (judgerun(date0) == 1 && date1 == 2 && 0 < date2 && date2 < 30) {
                    return true;
                } else if (0 < date2 && date2 <= month[date1 - 1]) {
                    return true;
                } else
                    return false;
            } else
                return false;
        }
    }
    public static boolean judgedate1(String date) {
        if(date.indexOf('/')==-1){
            return false;
        }else {
            String[] time = date.split("/");
            if (time[0].length() == 4 && (time[1].length() == 1 || time[1].length() == 2) && (time[2].length() == 1 || time[2].length() == 2)) {
                return true;
            } else
                return false;
        }
    }
    public static boolean judgeday(String daytime){
        try {
            String[] time = daytime.split("/");
            int date0 = Integer.parseInt(time[0]);
            int date1 = Integer.parseInt(time[1]);
            int date2 = Integer.parseInt(time[2]);
            if (0 <= date0 && date0 <= 24 && 0 <= date1 && date1 < 60 && 0 <= date2 && date2 < 60) {
                return true;
            } else
                return false;
        }catch (Exception e){
            return false;
        }
    }
    public static boolean judgeday1(String daytime){
        String[] time = daytime.split("/");
        if((time[0].length()==1||time[0].length()==2)&&(time[1].length()==1||time[1].length()==2)&&(time[2].length()==1||time[2].length()==2)){
            return true;
        }
        else
            return false;
    }
    public static boolean judgeyear(String year){
        String[] time = year.split("/");
        int date0 = Integer.parseInt(time[0]);
        int date1 = Integer.parseInt(time[1]);
        int date2 = Integer.parseInt(time[2]);
        if(2022<=date0&&date0<=2023&&1<=date1&&date1<=12&&1<=date2&&date2<=31){
            return true;
        }
        else
            return false;
    }
    public static boolean dateinterval(List<Integer> num, List<String> date, List<String> hour) {
        HashSet<Integer> set = new HashSet<>();
        for (int i = 0; i < num.size(); i++) {
            int n = num.get(i);
            if (set.contains(n)) {
                return false;
            }
            set.add(n);
        }
        for (int i = 1; i < num.size(); i++) {
            if (date.get(i).equals(date.get(i - 1))) {
                if (hour.size() >= 2) {
                    try {
                        SimpleDateFormat format = new SimpleDateFormat("HH/mm/ss");
                        Date date1 = format.parse(hour.get(0));
                        Date date2 = format.parse(hour.get(1));
                        long interval = Math.abs(date2.getTime() - date1.getTime()) / 1000; // 计算两个时间的秒数差值
                        if (interval <= 60 * 60) { // 判断时间差值是否在一小时之内
                            return false;
                        }
                    } catch (Exception e) {
                        return true;
                    }
                }
            }
        }
        return true;
    }

}

 

类图:

复杂度:

分析:

Dish类:表示菜品。

Menu类:表示菜单,用于管理菜单上的菜品。

Record类:表示订单记录。

Order类:表示订单,从一个订单中添加、删除和计算记录。

Table类:表示餐桌,用于管理桌上的订单。

Main类:主执行类,实现点餐系统的各种功能。

在主函数Main()中,代码通过Scanner输入命令的方式实现。命令包括菜单设置、桌号、点餐、删除菜品记录等。结束输入命令时,输入“end”。

代码对输入命令的正确性和合法性进行了严谨判断,如果输入错误,会给出相应的错误提示。

点餐系统核心功能包括:

1、添加、查找和修改菜品信息。

2、添加桌号和时间信息。

3、点菜、添加点菜记录并计算订单价格。

4、删除点菜记录。

5、计算各个餐桌的总价。

代码中还涉及到日期和时间的处理。在这部分代码中,对日期和星期、时间等的正确性进行了判断。例如判断输入的年份是否在2022和2023之间,判断输入的时间是否在营业时间内等。

整个程序实现了一个基本的点餐系统,具备了较好的错误提示。

2.4、菜单计价程序-5

题目:

本题在菜单计价程序-3的基础上增加了部分内容,增加的内容用加粗字体标识。

注意不是菜单计价程序-4,本题和菜单计价程序-4同属菜单计价程序-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+英文空格+桌号+“:”+英文空格+当前桌的总价

 

以上为菜单计价系列-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+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格

 

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

源码:

import java.util.*;
import java.time.LocalTime;
class Dish {
    String name;//菜品名称
    String dishtype;//菜品类型
    int unit_price;//单价
    boolean Tname; //特色菜
    public Dish(String name,String dishtype,int unit_price,boolean Tname){
        this.name = name;
        this.dishtype = dishtype;
        this.unit_price = unit_price;
        this.Tname = Tname;
    }
    public int getPrice(int portion){
        if(portion==1)
            return unit_price;
        else if(portion==2)
            return (int)Math.round(unit_price*1.5);
        else if(portion==3)
            return unit_price*2;
        else
            return 0;

    }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
    public String getName(){
        return name;
    }
}
class Menu {
    List<Dish> dishs=new ArrayList<>();//菜品数组,保存所有菜品信息
    Dish searthDish(String dishName){
        for(Dish dish:dishs){
            if(dish.name.equals(dishName)){
                return dish;
            }
        }
        return null;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    public boolean searthTDish(String dishName){
        for(Dish dish:dishs){
            if(dish.name.equals(dishName)) {
                if (dish.Tname) {
                    return true;
                }
            }
        }
        return false;
    }//判断是否是特色菜。
    public String finddishtype(String dishname){
        for(Dish dish:dishs){
            if(dish.name.equals(dishname)){
                return dish.dishtype;
            }
        }
        return null;
    }
    public void addDish(String dishName,String dishtype,int unit_price,boolean Tname){
        if(searthDish(dishName)==null){
            Dish newname = new Dish(dishName,dishtype,unit_price,Tname);
            dishs.add(newname);
        }else{
            searthDish(dishName).unit_price = unit_price;
        }
    }//添加一道菜品信息
}
class Record {
    int orderNum;//序号
    Dish d;//菜品
    int taste;
    int portion;//份额(1/2/3代表小/中/大份)
    int num;//表示份数
    boolean T;
    public Record(int orderNum,Dish d,int taste,int portion,int num,boolean T){
        this.orderNum = orderNum;
        this.d = d;
        this.taste = taste;
        this.portion = portion;
        this.num = num;
        this.T = T;
    }

    int getPrice(){
        return d.getPrice(portion)*num;
    }//计价,计算本条记录的价格\
}
class Order {
    List<Record> records;//保存订单上每一道的记录
    int tablenum;//桌号
    String name;//点菜人
    String phonenum;//电话号码
    String time;//时间
    String hour;//小时
    public Order(int tablenum,String name,String phonenum,String time,String hour) {
        this.tablenum = tablenum;
        this.name = name;
        this.phonenum = phonenum;
        this.time = time;
        this.hour = hour;
        this.records = new ArrayList<>();
    }
    public int getTotalPrice(){
        int total = 0;
        for(Record record:records){
            total += record.getPrice();
        }
        return total;
    }//计算订单的总价
    public int getfinalprice(){
        double total = 0;
        for(Record record:records){
            if(!record.d.Tname){
                total = total + Math.round(record.getPrice()*0.6);
            }
            else
                total = total + Math.round(record.getPrice()*0.7);
        }
        return (int)Math.round(total);
    }//计算周一到周五的中午总价
    public int getfinalprice1(){
        double total = 0;
        for(Record record:records){
            if(!record.d.Tname){
                total = total + Math.round(record.getPrice()*0.8);
            }
            else
                total = total + Math.round(record.getPrice()*0.7);
        }
        return (int)Math.round(total);
    }//计算周一到周五的晚上总价
    public void adddish(int orderNum,Dish dish,int taste,int portion,int num,boolean T){
        Record newrecord = new Record(orderNum,dish,taste,portion,num,T);
        newrecord.portion = 0;
        records.add(newrecord);
        //System.out.println(dish.getName());
    }//添加菜品
    public void addARecord(int orderNum,Dish dish,int taste,int portion,int num,boolean T){
        Record newrecord = new Record(orderNum,dish,taste,portion,num,T);
        records.add(newrecord);
        System.out.println(orderNum+" "+dish.getName()+" "+newrecord.getPrice());
    }//添加一条菜品信息到订单中。
    public void addARecords(int tablenum1,int tablenum2,int orderNum,Dish dish,int taste,int portion,int num,boolean T){
        Record newrecord = new Record(orderNum,dish,taste,portion,num,T);
        newrecord.taste = 0;
        newrecord.T = false;
        records.add(newrecord);
        System.out.println(orderNum+" table "+tablenum1+" pay for table "+ tablenum2 +" "+newrecord.getPrice());
    }//添加一条代点菜品信息到订单中。
    public boolean delARecordByOrderNum(int orderNum){
        Iterator<Record> iterator = records.iterator();
        while (iterator.hasNext()) {
            Record record = iterator.next();
            if (record.orderNum == orderNum) {
                iterator.remove();
                return true;
            }
        }
        return false;
    }//根据序号删除一条记录
    public boolean judgespicy(){
        for(Record record:records){
            if(record.d.dishtype.equals("川菜")&& record.T){
                return true;
            }
        }
        return false;
    }//判断是否是川菜
    public String getspicy(){
        int spicynum=0;
        for(Record record:records){
            if(record.d.dishtype.equals("川菜")){
                spicynum = spicynum+record.taste*record.num;
            }
        }
        spicynum = Math.round((float) spicynum /getspicynum());
        if(spicynum==0)
            return "不辣";
        else if (spicynum==1)
            return "微辣";
        else if (spicynum==2)
            return "稍辣";
        else if (spicynum==3)
            return "辣";
        else if (spicynum==4)
            return "很辣";
        else if (spicynum==5)
            return "爆辣";
        else
            return "0";
    }//计算川菜的口味度
    public int getspicynum(){
        int spicynum=0;
        for(Record record:records){
            if(record.d.dishtype.equals("川菜")){
                spicynum = spicynum+record.num;
            }
        }
        return spicynum;
    }//计算川菜的份数
    public boolean judgeacadity(){
        for(Record record:records){
            if(record.d.dishtype.equals("晋菜")&&record.T){
                return true;
            }
        }
        return false;
    }//判断是否是晋菜
    public String getacadity(){
        int acaditynum=0;
        for(Record record:records){
            if(record.d.dishtype.equals("晋菜")){
                acaditynum= acaditynum+record.taste*record.num;
            }
        }
        acaditynum = Math.round((float) acaditynum /getaciditynum());
        if(acaditynum==0)
            return "不酸";
        else if (acaditynum==1)
            return "微酸";
        else if (acaditynum==2)
            return "稍酸";
        else if (acaditynum==3)
            return "酸";
        else if (acaditynum==4)
            return "很酸";
        else
            return "0";
    }//计算鸡菜的口味度
    public int getaciditynum(){
        int acaditynum=0;
        for(Record record:records){
            if(record.d.dishtype.equals("晋菜")){
                acaditynum = acaditynum+record.num;
            }
        }
        return acaditynum;
    }//计算晋菜的份数
    public boolean judgesweetness(){
        for(Record record:records){
            if(record.d.dishtype.equals("浙菜")&&record.T){
                return true;
            }
        }
        return false;
    }//判断是否是浙菜
    public String getsweetness(){
        int sweetnessnum=0;
        for(Record record:records){
            if(record.d.dishtype.equals("浙菜")){
                sweetnessnum= sweetnessnum+record.taste*record.num;
            }
        }
        sweetnessnum = Math.round((float) sweetnessnum /getsewwtnessnum());
        if(sweetnessnum==0)
            return "不甜";
        else if (sweetnessnum==1)
            return "微甜";
        else if (sweetnessnum==2)
            return "稍甜";
        else if (sweetnessnum==3)
            return "甜";
        else
            return "0";
    }//计算浙菜的口味度
    public int getsewwtnessnum(){
        int sweetnessnum=0;
        for(Record record:records){
            if(record.d.dishtype.equals("浙菜")){
                sweetnessnum = sweetnessnum+record.num;
            }
        }
        return sweetnessnum;
    }//计算浙菜的份数
}
class Table{
    List<Order> tables;
    public Table(){
        this.tables = new ArrayList<>();
    }
    public void addtable(int tablenum,String name,String phonenum,String time,String hour) {
        Order newtable = new Order(tablenum,name,phonenum,time, hour);
        tables.add(newtable);
    }//添加桌号信息
    public int timeround(String yeartime){
        String[] time = yeartime.split("/");
        int[] times = new int[3];
        times[0] = Integer.parseInt(time[0]);
        times[1] = Integer.parseInt(time[1]);
        times[2] = Integer.parseInt(time[2]);
        Calendar Monthday = new GregorianCalendar(times[0], times[1] - 1, times[2]);
        int weekday = Monthday.get(Calendar.DAY_OF_WEEK) - 1;
        if (weekday == 0) {
            weekday = 7; // 将周日(Calendar.SUNDAY)转换为7
        }
        if(1<=weekday&&weekday<=5){
            return 0;
        }
        else
            return 1;
    }//判断是周几
    public Order searchOrder(int tableNum){
        for(Order order : tables){
            if(order.tablenum == tableNum){
                return order;
            }
        }
        return null;
    }//查找桌号
    public int totalmey(String yeartime,String daytime,int tablenum){
        String[] hour = daytime.split("/");
        int hours0 = Integer.parseInt(hour[0]);
        int hours1 = Integer.parseInt(hour[1]);
        int hours2 = Integer.parseInt(hour[2]);
        LocalTime t0 = LocalTime.of(hours0,hours1,hours2);
        LocalTime t1 = LocalTime.of(10,30,0);
        LocalTime t2 = LocalTime.of(14,30,0);
        LocalTime t3 = LocalTime.of(17,0,0);
        LocalTime t4 = LocalTime.of(20,30,0);
        LocalTime t5 = LocalTime.of(9,30,0);
        LocalTime t6 = LocalTime.of(21,30,0);
        if(timeround(yeartime)==0){
            if(t0.isAfter(t1)&&t0.isBefore(t2)||t0.equals(t1)||t0.equals(t2)){
                return 0;
            }
            else if(t0.isAfter(t3)&&t0.isBefore(t4)||t0.equals(t3)||t0.equals(t4)){
                return 1;
            }
            else {
                return -1;
            }
        }
        else if(timeround(yeartime)==1){
            if(t0.isAfter(t5)&&t0.isBefore(t6)||t0.equals(t5)||t0.equals(t6)){
                return 2;
            }
            else {
                return -1;
            }
        }
        else
            return -1;
    }//判断具体的时段
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Menu menu = new Menu();
        Table table = new Table();
        String inputmenu = input.nextLine();
        String[] delete = new String[50];
        String[] tablename = new String[10];
        boolean ordering = true;
        int[] tableprice = new int[10];
        String[] tablephone = new String[10];
        Map<String, Integer> map = new HashMap<>();
        int num = 0, i = 0,j=0,k=0,n=0,l=0;
        while (!inputmenu.equals("end")) {
            String[] inputmenus = inputmenu.split(" ");
            if (inputmenus.length == 2 && inputmenus[0].matches("^[\\u4e00-\\u9fa5]+") && inputmenus[1].matches("^\\d+$")) {//菜单
                if (judgemessage(inputmenus[1]) == 1 && 0<Integer.parseInt(inputmenus[1])&&Integer.parseInt(inputmenus[1])<300) {
                    menu.addDish(inputmenus[0], "0",Integer.parseInt(inputmenus[1]), false);
                } else
                    System.out.println("wrong format");//------------------菜单
            } else if (inputmenus.length == 4 && inputmenus[0].matches("^[\\u4e00-\\u9fa5]+$") && inputmenus[2].matches("^\\d+$")) {                     //菜单特色菜
                menu.addDish(inputmenus[0],inputmenus[1],Integer.parseInt(inputmenus[2]), true);
            } else if (inputmenus.length == 7 && inputmenus[0].matches("table") && inputmenus[1].matches("^\\d+$")) {//table   //桌号与时间
                num = Integer.parseInt(inputmenus[1]);
                if(judgephonelegal(inputmenus[4])) {
                    if (table.totalmey(inputmenus[5], inputmenus[6], Integer.parseInt(inputmenus[1])) != -1) {
                        System.out.println("table " + num + ": ");
                        table.addtable(num, inputmenus[3], inputmenus[4], inputmenus[5], inputmenus[6]);//桌号信息
                    } else
                        System.out.println("table " + num + " out of opening hours");
                }
                else {
                    System.out.println("wrong format");
                    ordering = false;
                }//------------------------------------------------桌号
            } else if ((inputmenus.length == 4||inputmenus.length == 5) && inputmenus[0].matches("\\d+$") && inputmenus[1].matches("^[\\u4e00-\\u9fa5]+$") && inputmenus[2].matches("\\d+") && inputmenus[3].matches("\\d+")) {       //点菜
                if(ordering) {
                    Dish dish = menu.searthDish(inputmenus[1]);
                    if (dish != null) {
                        if (menu.searthTDish(dish.name)) {
                            if (finddishtype(menu.finddishtype(dish.name), Integer.parseInt(inputmenus[2])) == 0) {
                                table.searchOrder(num).addARecord(Integer.parseInt(inputmenus[0]), dish, Integer.parseInt(inputmenus[2]), Integer.parseInt(inputmenus[3]), Integer.parseInt(inputmenus[4]),true);
                            }
                        } else
                            table.searchOrder(num).addARecord(Integer.parseInt(inputmenus[0]), dish, -1, Integer.parseInt(inputmenus[2]), Integer.parseInt(inputmenus[3]),false);

                    } else
                        System.out.println(inputmenus[1] + " " + "does not exist");//---------点菜记录
                }
            } else if ((inputmenus.length == 5||inputmenus.length==6) && inputmenus[0].matches("\\d+$") && inputmenus[1].matches("\\d+") && inputmenus[2].matches("^[\\u4e00-\\u9fa5]+$")) {       //点菜
                if(ordering) {
                    Dish dish = menu.searthDish(inputmenus[2]);
                    if(table.searchOrder(Integer.parseInt(inputmenus[0]))!=null&&table.searchOrder(Integer.parseInt(inputmenus[0])).tablenum==Integer.parseInt(inputmenus[0])) {
                        if (dish != null) {
                            if (menu.searthTDish(dish.name)) {
                                table.searchOrder(Integer.parseInt(inputmenus[0])).adddish(Integer.parseInt(inputmenus[1]), dish, Integer.parseInt(inputmenus[3]), Integer.parseInt(inputmenus[4]), Integer.parseInt(inputmenus[5]), true);
                                table.searchOrder(num).addARecords(num, Integer.parseInt(inputmenus[0]), Integer.parseInt(inputmenus[1]), dish, -1, Integer.parseInt(inputmenus[4]), Integer.parseInt(inputmenus[5]), true);
                            } else {
                                table.searchOrder(Integer.parseInt(inputmenus[0])).adddish(Integer.parseInt(inputmenus[1]), dish, -1, Integer.parseInt(inputmenus[3]), Integer.parseInt(inputmenus[4]), false);
                                table.searchOrder(num).addARecords(num, Integer.parseInt(inputmenus[0]), Integer.parseInt(inputmenus[1]), dish, -1, Integer.parseInt(inputmenus[3]), Integer.parseInt(inputmenus[4]), false);

                            }
                        } else
                            System.out.println(inputmenus[1] + " " + "does not exist");//---------代点菜信息
                    }
                    else
                        System.out.println("Table number : "+inputmenus[0] +" does not exist");
                }
            }else if (inputmenus.length == 2 && inputmenus[0].matches("\\d+")) {//删除菜品信息
                if (!table.searchOrder(num).delARecordByOrderNum(Integer.parseInt(inputmenus[0]))) {
                    System.out.println("delete error;");
                }
                //delete[n] = inputmenus[0];//----------------------------删除菜品
            }
            else
                System.out.println("wrong format");

            inputmenu = input.nextLine();
        }
        for (Order order : table.tables) {
            if(order.judgeacadity()&&order.judgesweetness()&&order.judgespicy()) {//三种菜都有
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice() +" 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy()+" 晋菜" + " " + order.getaciditynum() + " " + order.getacadity()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice() +" 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
            }
            else if(order.judgespicy()&&order.judgeacadity()) {//有川菜和晋菜
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity());
                }
            }
            else if(order.judgespicy()&&order.judgesweetness()) {//川菜和浙菜
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
            }
            else if(order.judgeacadity()&&order.judgesweetness()) {//晋菜和浙菜
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice() + " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1() + " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice() + " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity()+ " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
            }
            else if(order.judgespicy()) {//川菜
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice() + " 川菜" + " " + order.getspicynum() + " " + order.getspicy());
                }
            }
            else if(order.judgeacadity()) {//晋菜
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice() + " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1() + " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice() + " 晋菜" + " " + order.getaciditynum() + " " + order.getacadity());
                }
            }
            else if(order.judgesweetness()) {//浙菜
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice() + " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1() + " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice() + " 浙菜" + " " + order.getsewwtnessnum() + " " + order.getsweetness());
                }
            }
            else{//都没有
                if (table.totalmey(order.time, order.hour, order.tablenum) == 0) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice()+" ");
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 1) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getfinalprice1()+" ");
                }
                else if (table.totalmey(order.time, order.hour, order.tablenum) == 2) {
                    System.out.println("table " + order.tablenum + ": " + order.getTotalPrice() + " " + order.getTotalPrice()+" ");
                }
            }
        }
        for (Order orde: table.tables){
            if (table.totalmey(orde.time, orde.hour, orde.tablenum) == 0) {
                tablename[i] = orde.name;
                tablephone[k] = orde.phonenum;
                tableprice[j] = orde.getfinalprice();
                if (map.containsKey(tablename[i])) {
                    // 如果存在,将新的数字加到已有的数字上
                    map.put(tablename[i], map.get(tablename[i]) + tableprice[i]);
                    tablephone[k] = "0";
                } else {
                    // 如果不存在,直接将单词和数字存入Map
                    map.put(tablename[i], tableprice[i]);
                }
                k++;
                i++;
                j++;
            }
            else if (table.totalmey(orde.time, orde.hour, orde.tablenum) == 1) {
                tablename[i] = orde.name;
                tablephone[k] = orde.phonenum;
                tableprice[j] = orde.getfinalprice1();
                if (map.containsKey(tablename[i])) {
                    // 如果存在,将新的数字加到已有的数字上
                    map.put(tablename[i], map.get(tablename[i]) + tableprice[i]);
                    System.out.println(map);
                    tablephone[k] = "0";
                } else {
                    map.put(tablename[i], tableprice[i]);
                }
                k++;
                i++;
                j++;
            }
            else if (table.totalmey(orde.time, orde.hour, orde.tablenum) == 2) {
                tablename[i] = orde.name;
                tablephone[k] = orde.phonenum;
                tableprice[j] = orde.getTotalPrice();
                if (map.containsKey(tablename[i])) {
                    // 如果存在,将新的数字加到已有的数字上
                    map.put(tablename[i], map.get(tablename[i]) + tableprice[i]);
                    tablephone[k] = "0";
                } else {
                    // 如果不存在,直接将单词和数字存入Map
                    map.put(tablename[i], tableprice[i]);
                }
                k++;
                i++;
                j++;
            }
        }
        List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
        list.sort(Map.Entry.comparingByKey());
        int a=0;
        for (Map.Entry<String, Integer> entry : list) {
            tablename[a] = entry.getKey();
            a++;
        }
        //int b=0;
        for(Order o: table.tables){//输出姓名/电话和总价
            for(int b=0;b<a;b++)
                if(o.name.matches(tablename[b])){
                tablephone[b]=o.phonenum;
            }
        }
        for (Map.Entry<String, Integer> entry : list) {
            System.out.println(entry.getKey() + " " +tablephone[l]+" "+ entry.getValue());
            l++;
        }
    }
    public static int judgemessage(String figure) {//判断输入的数字是否合法
        try {
            int num = Integer.parseInt(figure);
            // 判断最高位是否为零
            if (figure.charAt(0) == '0') {
                //System.out.println("最高位为零");
                return 0;
            }
            return 1;
        } catch (NumberFormatException e) {
            //System.out.println("错误格式");
            return 0;
        }
    }
    public static int finddishtype(String dishnametype,int num) {//判断口味度是否超出范围
        switch (dishnametype) {
            case "川菜":
                if (0 <= num && num <= 5) {
                    return 0;
                } else
                    System.out.println("spicy num out of range :" + num);
                break;
            case "晋菜":
                if (0 <= num && num <= 4) {
                    return 0;
                } else
                    System.out.println("acidity num out of range :" + num);
                break;
            case "浙菜":
                if (0 <= num && num <= 3) {
                    return 0;
                } else
                    System.out.println("sweetness num out of range :" + num);
                break;
        }
        return -1;
    }
    public static boolean judgephonelegal(String phonenum){//判断电话号码是否合格
        String phone = phonenum.substring(0,3);
        if(phonenum.length()!=11){
            return false;
        }
        else return phone.equals("180") || phone.equals("181") || phone.equals("189") || phone.equals("133") || phone.equals("135") || phone.equals("136");
    }
}

 

类图:

复杂度:

分析

Dish 类:表示菜品,包括菜品名称、菜品类型、单价等属性,以及计算菜品价格的方法。

Menu 类:表示菜单,包含一系列的菜品信息。主要提供添加菜品、查找菜品等功能。

Record 类:表示订单上的一条记录,包含菜品、口味、份额等信息,以及计算该记录价格的方法。

Order 类:表示一个订单,包含桌号、姓名、电话号码、时间等信息,以及添加记录、删除记录、计算总价等功能。

Table 类:表示所有的订单,包含一系列的订单信息。主要提供添加桌号、查找桌号等功能。

main 函数:主要负责接收用户输入,并根据输入执行相应的功能

期中考试:

2.5、测验1-圆类设计

题目

创建一个圆形类(Circle),私有属性为圆的半径,从控制台输入圆的半径,输出圆的面积

输入格式:

输入圆的半径,取值范围为(0,+∞),输入数据非法,则程序输出Wrong Format,注意:只考虑从控制台输入数值的情况

输出格式:

输出圆的面积(保留两位小数,可以使用String.format(“%.2f”,输出数值)控制精度)

源码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double radius = scanner.nextDouble();
        if (radius > 0) {
            Circle circle = new Circle();
            circle.setRadius(radius);
            double area = circle.getArea();
            System.out.println(String.format("%.2f", area));
        } else {
            System.out.println("Wrong Format");
        }
    }
}
class Circle {
    private double radius;

    public Circle() {
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

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

}

 

类图:

复杂度:

分析:

首先,导入了java.util.Scanner类,用于读取用户输入。

在main方法中,创建了一个Scanner对象scanner,用于接收用户输入。

接下来,从用户输入中获取一个double类型的半径值,并将其赋给变量radius。

如果半径值大于0,则创建一个Circle对象circle,并调用其setRadius方法设置半径值。

接着,调用circle对象的getArea方法获取圆的面积,并将结果赋给变量area。

最后,使用System.out.println输出面积值。在输出之前,使用String.format("%.2f", area)格式化面积值,保留两位小数。

如果半径值小于等于0,则输出"Wrong Format"。

Circle类是一个简单的圆形类,具有私有的radius属性,以及设置半径和获取面积的方法。

2.6、测验2-类结构设计

题目:

设计一个矩形类,其属性由矩形左上角坐标点(x1,y1)及右下角坐标点(x2,y2)组成,其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数),求得该矩形的面积。类设计如下图:

源码:

import java.util.Scanner;
class Point{
    double x;
    double y;
    public Point(){}
    public void setX(double x){
        this.x = x;
    }
    public double getX(){
        return x;
    }
    public void sety(double y){
        this.y = y;
    }
    public double getY(){
        return y;
    }
}
class Rectangle{
    Point topLeftPoint;
    Point lowerRightPoint;
    public Rectangle(){

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

    public void setTopLeftPoint(Point topLeftPoint) {
        this.topLeftPoint = topLeftPoint;
    }
    public Point getTopLeftPoint(){
        return topLeftPoint;
    }
    public void setLowerRightPoint(Point lowerRightPoint){
        this.lowerRightPoint =lowerRightPoint;
    }
    public Point getLowerRightPoint(){
        return lowerRightPoint;
    }
    public double getLength(){
        return Math.abs(topLeftPoint.y - lowerRightPoint.y);
    }
    public double getHeihgt(){
        return Math.abs(topLeftPoint.x - lowerRightPoint.x);
    }
    public double getArea(){
        return getHeihgt()*getLength();
    }
}
public class Main {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        double x1 = input.nextDouble();
        double y1 = input.nextDouble();
        double x2 = input.nextDouble();
        double y2 = input.nextDouble();
        Rectangle rctangle = new Rectangle();
        Point topLeft = new Point();
        topLeft.setX(x1);
        topLeft.sety(y1);
        Point lowerRight = new Point();
        lowerRight.setX(x2);
        lowerRight.sety(y2);
        rctangle.setTopLeftPoint(topLeft);
        rctangle.setLowerRightPoint(lowerRight);
        System.out.println(String.format("%.2f",rctangle.getArea()));
    }
}

 

类图:

复杂度:

分析:

1、首先,导入了java.util.Scanner类,用于读取用户输入。

2、定义了一个Point类,表示一个点的坐标,包括x和y两个属性。该类具有设置和获取坐标值的方法。

3、定义了一个Rectangle类,表示一个矩形,包括左上角点和右下角点两个属性。该类具有设置和获取左上角点和右下角点的方法,以及计算矩形长度、宽度和面积的方法。

4、在main方法中,创建了一个Scanner对象input,用于接收用户输入。

5、从用户输入中获取四个double类型的坐标值,并将它们赋给变量x1、y1、x2、y2。

6、创建Rectangle对象rctangle和两个Point对象topLeft、lowerRight。

7、调用topLeft和lowerRight对象的setX和setY方法,设置它们的坐标值。

8、调用rctangle对象的setTopLeftPoint和setLowerRightPoint方法,分别将topLeft和lowerRight对象设置为矩形的左上角点和右下角点。

9、调用rctangle对象的getArea方法获取矩形的面积,并使用String.format("%.2f", rctangle.getArea())格式化面积值,保留两位小数。

10、最后,使用System.out.println输出面积值。

2.7、测验3-继承与多态

题目:

将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类

源码:

import java.util.Scanner;

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 radiums = input.nextDouble();
                if (radiums <= 0) {
                    System.out.println("Wrong Format");
                    return;
                }
                Shape circle = new Circle(radiums);
                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);
                Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
                printArea(rectangle);
                break;
        }
    }

    public static void printArea(Shape shape) {
        System.out.printf("%.2f", shape.getArea());
    }
}
abstract class Shape {
    public abstract double getArea();
}

class Circle extends Shape {
    private double radiums;

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

    @Override
    public double getArea() {
        return Math.PI * radiums * radiums;
    }
}

class Rectangle extends Shape {
    private Point leftTopPoint;
    private Point lowerRightPoint;
    public Rectangle(Point leftTopPoint, Point lowerRightPoint) {
        this.leftTopPoint = leftTopPoint;
        this.lowerRightPoint = lowerRightPoint;
    }
    public void setTopLeftPoint(Point topLeftPoint) {
        this.leftTopPoint = topLeftPoint;
    }
    public Point getTopLeftPoint(){
        return leftTopPoint;
    }
    public void setLowerRightPoint(Point lowerRightPoint){
        this.lowerRightPoint =lowerRightPoint;
    }
    public Point getLowerRightPoint(){
        return lowerRightPoint;
    }
    public double getLength(){
        return Math.abs(leftTopPoint.getY() - lowerRightPoint.getY());
    }
    public double getHeihgt(){
        return Math.abs(leftTopPoint.getX()- lowerRightPoint.getX());
    }
    @Override
    public double getArea() {
        return getHeihgt()*getLength();
    }
}

class Point {
    private double x;
    private double y;
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }
}

 

类图:

复杂度:

分析:

1、首先,导入了java.util.Scanner类,用于读取用户输入。

2、定义了一个抽象类Shape,表示一个图形,其中包含一个抽象方法getArea()用于计算图形的面积。

3、定义了一个Circle类,继承自Shape类,表示一个圆形,其中包含一个私有属性radiums表示半径,以及实现了父类的getArea()方法来计算圆形的面积。

定义了一个Point类,表示一个点的坐标,包括x和y两个属性。该类具有设置和获取坐标值的方法。

4、定义了一个Rectangle类,继承自Shape类,表示一个矩形,其中包含两个私有属性leftTopPoint和lowerRightPoint,分别表示矩形的左上角和右下角的坐标点。该类具有设置和获取左上角点和右下角点的方法,以及计算矩形长度、宽度和面积的方法。

5、在main方法中,创建了一个Scanner对象input,用于接收用户输入。

6、从用户输入中获取一个整数choice,代表用户选择的图形类型。

7、使用switch语句根据用户选择的图形类型执行相应的操作:

8、如果choice为1,表示用户选择圆形,从用户输入中获取一个double类型的半径值radiums,并创建Circle对象circle,然后调用printArea方法输出圆形的面积。

9、如果choice为2,表示用户选择矩形,从用户输入中获取四个double类型的坐标值x1、y1、x2、y2,并创建Point对象leftTopPoint和lowerRightPoint,然后创建Rectangle对象rectangle,调用printArea方法输出矩形的面积。

10、printArea方法接收一个Shape类型的参数shape,调用shape对象的getArea方法获取图形的面积,并使用System.out.printf("%.2f", shape.getArea())格式化面积值,保留两位小数。

最后,定义了一个抽象类Shape和几个具体的类Circle、Rectangle、Point,通过继承和组合的方式实现了不同图形的面积计算功能,并根据用户的选择进行相应的计算和输出。

2.8、测验4-抽象类与接口

题目:

在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。

源码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
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 radiums = input.nextDouble();
                    Shape circle = new Circle(radiums);
                    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);
                    Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
                    list.add(rectangle);
                    break;
            }
            choice = input.nextInt();
        }

        Collections.sort(list);

        for (int i = 0; i < list.size(); i++) {
            System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
        }
    }
}
abstract class Shape implements Comparable<Shape> {
    public abstract double getArea();

    @Override
    public int compareTo(Shape shape) {
        return Double.compare(this.getArea(), shape.getArea());
    }
}
class Circle extends Shape {
    private final double radiums;
    public Circle(double radiums) {
        this.radiums = radiums;
    }
    @Override
    public double getArea() {
        return Math.PI * radiums * radiums;
    }
}

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

    public Rectangle(Point leftTopPoint, Point lowerRightPoint) {
        this.leftTopPoint = leftTopPoint;
        this.lowerRightPoint = lowerRightPoint;
    }
    public void setTopLeftPoint(Point topLeftPoint) {
        this.leftTopPoint = topLeftPoint;
    }
    public Point getTopLeftPoint(){
        return leftTopPoint;
    }
    public void setLowerRightPoint(Point lowerRightPoint){
        this.lowerRightPoint =lowerRightPoint;
    }
    public Point getLowerRightPoint(){
        return lowerRightPoint;
    }
    public double getLength(){
        return Math.abs(leftTopPoint.getY() - lowerRightPoint.getY());
    }
    public double getHeihgt(){
        return Math.abs(leftTopPoint.getX()- lowerRightPoint.getX());
    }
    @Override
    public double getArea() {
        return getHeihgt()*getLength();
    }
}
class Point {
    private double x;
    private double y;

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

 

类图:

复杂度:

分析:

1、首先,导入了java.util.ArrayList、java.util.Collections和java.util.Scanner类。

2、定义了一个主类Main,其中包含了main方法。

3、在main方法中,创建了一个Scanner对象input,用于接收用户输入。

4、创建了一个ArrayList<Shape>对象list,用于存储不同图形的实例。

5、从用户输入中获取一个整数choice,代表用户选择的图形类型。

6、使用while循环,当choice不为0时执行循环体。

7、使用switch语句根据用户选择的图形类型执行相应的操作:

如果choice为1,表示用户选择圆形,从用户输入中获取一个double类型的半径值radiums,并创建Circle对象circle,然后将circle对象添加到list中。

如果choice为2,表示用户选择矩形,从用户输入中获取四个double类型的坐标值x1、y1、x2、y2,并创建Point对象leftTopPoint和lowerRightPoint,然后创建Rectangle对象rectangle,将rectangle对象添加到list中。

8、重新获取用户输入的choice,进入下一次循环。

9、使用Collections.sort()方法对list进行排序,排序依据是每个Shape对象的面积大小,需要确保Shape类实现了Comparable接口,并重写了compareTo方法。

10、使用for循环遍历list,调用每个Shape对象的getArea方法获取面积,并将面积保留两位小数后输出。

11、定义了一个抽象类Shape,实现了Comparable<Shape>接口,其中包含一个抽象方法getArea()用于计算图形的面积,并实现了compareTo方法用于比较不同Shape对象的面积大小。

12、定义了一个Circle类,继承自Shape类,表示一个圆形,其中包含一个私有属性radiums表示半径,以及实现了父类的getArea()方法来计算圆形的面积。

13、定义了一个Rectangle类,继承自Shape类,表示一个矩形,其中包含两个私有属性leftTopPoint和lowerRightPoint,分别表示矩形的左上角和右下角的坐标点。该类具有设置和14、获取坐标点的方法,以及计算矩形长度、宽度和面积的方法。

15、定义了一个Point类,表示一个点的坐标,包括x和y两个属性。该类具有设置和获取坐标值的方法。

16、最后,通过继承和组合的方式实现了不同图形的面积计算功能,并根据面积大小进行排序和输出。

三、踩坑新得

在编程过程中,遇到的最主要的困难是如何动态地维护订单记录。初次尝试使用ArrayList实现,但是由于缺少经验,调试的过程中出现了许多语法和调用接口的错误,比较耗费时间和精力。后来改用数组实现,避免了该问题。对于这种情况建议以后可以更加认真地处理好数据结构的选择和数组动态增长的实现机制,在实现过程中及时进行调试和测试。

另外,在编程过程中还发现自己还有很多不足之处,如对Java类与对象的定义和使用不够熟练,函数命名语义不够准确等,需要加强学习和练习。

四、主要困难以及改进意见

1、对类的创建对于新手来说一定要按照标准的格式来写,不能随心所欲该有的一定要有,切勿按照自己的意愿来写。各种相关类之间的调用以及主类中函数的编写和调用方式。

不熟悉各个模块之间的关系,写了这个就会忘记那个。

2、在以后的代码编写中要学会写注释,一边写了以后自己和他人的理解。要注重面向对象的编程而不是面向过程的编程。

例如

下一次尽量让主类里面只有输入和输出而其他的一切都在类里面或者函数里面。

五、总结

通过这三次题目集的学习,掌握了基本的输入输出、运算符、条件判断和循环结构的使用,学会了如何实现类的定义、构造函数、函数重载、数组、继承和封装,以及面向对象的编程思想和设计,对类之间的协作和关系有了更加深入的理解,

在以后的学习中,需要进一步加强对Java类与对象的理解和使用,掌握更多的编程技巧和设计模式,提高编程能力和效率。对于教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见,建议加强实践操作与实际问题的解决能力、加强问题分析和解决能力,开展更有针对性的实践和探究活动。

posted @ 2023-11-18 21:53  21207304  阅读(9)  评论(0)    收藏  举报