第二次pta大作业

发布时间 2023-11-19 20:53:11作者: Lvhiu

PTA第二次大作业

(1)前言:

       本次博客是对之前发布的PTA题目集4、5、6以及期中考试的总结性Blog,难度还是挺大的。具体详情如下:

       第四次题目集主要包括四道题目,第一题是单词统计与排序,主要是对字符串的分割、排序的处理,本题主要是HashSet的应用;第二题是判断两个日期的先后,计算间隔天数、周数,通过Java自带的日期类中的函数来对判断两个日期的先后,并计算它们之间间隔的天数、周数(不足一周按0计算);第三题是7-4 菜单计价程序-2,这是菜单计价的第二个版本,主要有菜单和订单两个部分,通过所给订单来计算价格,其中包含四个类,我在类的调用和返回值遇到了比较多的bug,具体在下面再说明。第四题是7-1 菜单计价程序-3 ,这是菜单计价的第三个版本,在前一个版本的基础上增加了桌号和带点菜的信息,相对前两次的菜单计价程序,这次的题目明显复杂许多,在菜单计价程序2的基础上,添加了桌号,也就是说订单不再是只对一个用户,而是对若干桌的顾客,而且桌号的条件下,还有代点菜的功能, 而且还添加了时间的概念,也就是说饭店有固定的开放时间和对应的折扣,这里的内容其实是比较复杂的,最后我们也不再是输出单个的总价,而是要按照点菜的桌号顺序依次输出每一桌的总价。

       第五次题目集只有菜单计价程序-4,是在菜单3的基础上对很多异常值的处理,增加了异常类来对异常输入的判断,真的很麻烦,写了很久也没有完全通过,还是自己写的真的有点慢加上时间不太够的原因。

       第六次题目集 是菜单计价程序-5,在菜单3的基础上增加了对特色菜的处理和客户订多桌饭的情况,思路算比较简单吧,但对自己的类修改了很多次,写代码之前还是要把类和具体逻辑先想好,边写边改真的很痛苦。

      本次期中考试不太理想,对文本知识掌握的比较少,视频没有怎么看,在编程题第二题卡了很久很久,一开始以为是类的处理有bug,但是一直没有找出来,后来发现是输入的问题,我是用nextLine输入一行数据,再用空格分隔,后来发现nextLine对小数点的处理并不是自己想象的那样,以后不偷懒用nextLine了,以至于后面两题没有时间了。以后还是要对理论知识点多花费时间,打代码的速度也是真慢。
 

(2)设计与分析:

第四次题目集

7-2 单词统计与排序

分数 10
作者 张峰
单位 山东科技大学

从键盘录入一段英文文本(句子之间的标点符号只包括“,”或“.”,单词之间、单词与标点之间都以" "分割。
要求:按照每个单词的长度由高到低输出各个单词(重复单词只输出一次),如果单词长度相同,则按照单词的首字母顺序(不区分大小写,首字母相同的比较第二个字母,以此类推)升序输出。

输入格式:

一段英文文本。

输出格式:

按照题目要求输出的各个单词(每个单词一行)。

输入样例:

Hello, I am a student from China.

输出样例:

student
China
Hello
from
am
a
I
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
 
解题思路:本题比较简单,按照正常逻辑走,基本都是语法问题,主要通过输入的文本,用“,”或“.”,单词之间、单词与标点之间都以" "分割,再对分割完的字符串进行排序,以下为具体思路:
  • 从标准输入读取一行字符串。
  • 将字符串按空格和标点符号分割成单词数组。
  • 使用HashSet去除重复单词,然后转换为列表。
  • 定义比较器对单词列表进行排序。
  • 遍历排序后的单词列表,依次输出每个单词。
主要包含以下知识点:
  1. 字符串处理:使用split方法将输入的字符串按空格和标点符号分割成单词数组。

  2. 集合:使用HashSet来去除重复单词,使用Arrays.asList将单词数组转换为集合。

  3. 比较器:定义了一个比较器Comparator,用来对单词进行排序。比较器首先按照单词长度降序排序,如果长度相同则按忽略大小写的字母顺序排序。

  4. 列表排序:将单词集合转换为列表,并使用Collections.sort方法对列表进行排序,传入自定义的比较器。

具体代码和代码的质量分析如下:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        String text = s.nextLine();
        String[] words = text.split("[\\s,.]+");
        Set<String> wordSet = new HashSet<>(Arrays.asList(words));//哈希
        // 定义比较器
        Comparator<String> comparator = (s1, s2) -> {
            if (s1.length() != s2.length()) {
                return s2.length() - s1.length(); // 按长度降序排序
            } else {
                return s1.compareToIgnoreCase(s2); // 长度相同按忽略大小写的字母顺序排序
            }
        };
        List<String> wordList = new ArrayList<>(wordSet);
        Collections.sort(wordList, comparator);

        for (String word : wordList) {
            System.out.println(word);
        }
    }
}

 

7-3 判断两个日期的先后,计算间隔天数、周数

分数 10
作者 吴光生
单位 新余学院

从键盘输入两个日期,格式如:2022-06-18。判断两个日期的先后,并输出它们之间间隔的天数、周数(不足一周按0计算)。

预备知识:通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。

输入格式:

输入两行,每行输入一个日期,日期格式如:2022-06-18

输出格式:

第一行输出:第一个日期比第二个日期更早(晚)
第二行输出:两个日期间隔XX天
第三行输出:两个日期间隔XX周

输入样例1:

2000-02-18
2000-03-15

输出样例1:

第一个日期比第二个日期更早
两个日期间隔26天
两个日期间隔3周

输入样例2:

2022-6-18
2022-6-1

输出样例2:

第一个日期比第二个日期更晚
两个日期间隔17天
两个日期间隔2周
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
 
解题思路:本题比较简单,按照正常逻辑走,通过日期函数获取年月日信息,在使用函数时要特别注意函数的使用格式,对不符合格式的日期要进行修改,以下为具体思路:
  • 从标准输入读取两个日期字符串。
  • 将日期字符串按照"-"分割成年、月、日三个部分,并将其存储在数组data1和data2中。
  • 将年份和月份的字符串转换为整数类型,以便后续处理。如果年份或月份小于10,则在字符串前面添加一个"0",以保证日期格式的一致性。
  • 将年、月、日拼接成标准日期格式"yyyy-MM-dd",并使用LocalDate类的parse方法将其转换为LocalDate类型。
  • 使用ChronoUnit类的DAYS和WEEKS方法计算两个日期之间的天数和周数。
  • 使用LocalDate类的isBefore方法判断两个日期的先后关系。

主要包含以下知识点:

  1. 字符串处理:使用split方法将日期字符串按照"-"分割成年、月、日三个部分,并将其存储在数组data1和data2中。

  2. 类型转换:将年份和月份的字符串转换为整数类型,以便后续处理。如果年份或月份小于10,则在字符串前面添加一个"0",以保证日期格式的一致性。

  3. 日期计算:将年、月、日拼接成标准日期格式"yyyy-MM-dd",并使用LocalDate类的parse方法将其转换为LocalDate类型。然后使用ChronoUnit类的DAYS和WEEKS方法计算两个日期之间的天数和周数。

  4. 日期比较:使用LocalDate类的isBefore方法判断两个日期的先后关系。

具体代码和代码的质量分析如下:

//package date;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;

public class Main{

    public static void main(String[] args) {
          Scanner s=new Scanner(System.in);
          String b=s.next();String c=s.next();
          String[] data1 = b.split("-");String[] data2 = c.split("-");
           int y1=Integer.valueOf(data1[1]);int y2=Integer.valueOf(data2[1]);
           int m1=Integer.valueOf(data1[2]);int m2=Integer.valueOf(data2[2]);
           if(y1<10) data1[1]="0"+y1;
           if(y2<10) data2[1]="0"+y2;
           if(m1<10) data1[2]="0"+m1;
           if(m2<10) data2[2]="0"+m2;
           b=data1[0]+"-"+data1[1]+"-"+data1[2];
           c=data2[0]+"-"+data2[1]+"-"+data2[2];
           LocalDate startDate = LocalDate.parse(b);
           LocalDate endDate = LocalDate.parse(c);
           if(endDate.isBefore(startDate)) 
               System.out.print("第一个日期比第二个日期更晚\n"); 
           else System.out.print("第一个日期比第二个日期更早\n"); 
           System.out.print("两个日期间隔"+Math.abs(ChronoUnit.DAYS.between(startDate, endDate))+"天\n"); 
           System.out.print("两个日期间隔"+Math.abs(ChronoUnit.WEEKS.between(startDate, endDate))+"周\n"); 
      
      
  }
}

 

7-4 菜单计价程序-2

分数 40
作者 蔡轲
单位 南昌航空大学

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

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

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

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


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

删除记录格式:序号 delete

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

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

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

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

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

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

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

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

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

Order {
   Record[] records;//保存订单上每一道的记录
   int getTotalPrice()//计算订单的总价
   Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。
   delARecordByOrderNum(int orderNum)//根据序号删除一条记录
   findRecordByNum(int orderNum)//根据序号查找一条记录
}

输入格式:

菜品记录格式:

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

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

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

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


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

输出格式:

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

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

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

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

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

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end

输出样例:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
63

输入样例1:

订单中包含删除记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end

输出样例1:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
27

输入样例2:

订单中包含不存在的菜品记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
end

输出样例2:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
63

输入样例3:

订单中包含删除信息以及不存在的菜品记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 delete
7 delete
end

输出样例3:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
27

输入样例4:

订单中包含删除信息以及不存在的菜品记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
end

输出样例4:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
delete error;
63
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
 
解题思路:
本题主要包含五个类:
  • Menu类:属性包括一个菜品数组,用来存储菜品类
  • Dish类:属性包括菜品名称和单价,描述菜品信息
  • Order类:存储点菜记录的信息
  • Record类:包括四个属性:点菜序号、菜品、份额、份数
  • Tranform类:对输入的信息进行判断属于哪种类型

Main函数通过输入处理类获得输入类型

  • 输入菜品信息:得到此条信息的菜品类,查找该菜品是否已存在,若不存在则加入到Menu中,否则直接将基础单价改为当前单价即可
  • 输入点菜记录:同样对输入进行处理得到一个Order类,再判断合法性,查找是否存在当前菜品,根据相应结果给出相应输出
  • 输入删除记录:同理,不存在的删除序号输出相应信息

最后输出总价。

具体类体如下所示:

 

 具体代码和代码的质量分析如下:

import java.util.Scanner;

class Dish {
    String name;//菜品名称
    int price; //单价
    public Dish(String name,int price){
        this.name = name;
        this.price = price;
    }
    public  int getprice(int portion,int dishsum){
        if(portion==1) {
            return price*dishsum;
        }
        else if(portion==2) {
            int Iprice = (int) (price*1.5);
            if(price-Iprice>=0.5){
                return (Iprice+1)*dishsum;
            }
            else {
                return Iprice*dishsum;
            }
        }
        else if(portion==3) {
            return price*2*dishsum;
        }
        return 0;
    }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份;
}

class Menu {

    Dish[] dishs = new Dish[100];

    public Dish searthDish(String dishName){
        for(int i=0;i<dishs.length;i++) {
            if(dishs[i]!=null && dishs[i].name.equals(dishName)) {
                return dishs[i];
            }
        }
        return null;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    public Dish addDish(String dishName,int price){
        Dish dish = new Dish(dishName,price);
        for(int i=0;i<dishs.length;i++){
            if(dishs[i]==null){
                dishs[i] = dish;
                break;
            }
        }
        return dish;
    }
}

class Order {
    Record[] records = new Record[100];//保存订单上每一道的记录
    public int getTotalPrice() {
        int sum = 0;
        for(int i=0;i<records.length;i++) {
            if(records[i]!=null) {
                records[i].getPrice();
                sum+=records[i].getPrice();
            }
        }
        return sum;
    }
    public Record addARecord(int id,Dish dish,int portion,int dishsum){
        //Menu menu = new Menu();
        //Dish dish = menu.searthDish(dishName);
        Record record = new Record(dish,portion,dishsum);
        records[id] = record;
        return record;
    }
    //添加一条菜品信息到订单中。
    public Record findRecordByNum(int id){
        return records[id];
    }
    public Record delARecordByOrderNum(int id){
        records[id]=null;
        return null;
    }
}

class Record {
    int dishsum;
    Dish d;//菜品
    int portion;//份额(1/2/3代表小/中/大份)
    public Record(Dish dish, int portion,int dishsum){
        this.dishsum = dishsum;
        this.d=dish;
        this.portion=portion;
    }
    int getPrice(){
        int price = d.getprice(portion,dishsum);
        return price;
    }//计价,计算本条记录的价格
}

class Tranform {
    public int getsize(String[] split) {
        String id = split[0];
        String[] arr = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
        for (int i = 0; i < 9; i++) {
            if (id.substring(0, 1).equals(arr[i])) {
                String cd = split[1];
                if (cd.equals("delete")) {
                    return 3;
                } else {
                    return 2;
                }
            }
        }
        return 1;
    }
}
public class Main {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        Menu menu = new Menu();
        Order order = new Order();
        Tranform tranform = new Tranform();
        String s;
        String name;
        int price;
        int portion;
        int id;
        int a;
        int dishsum;
        while(true){
            s = input.nextLine();
            String[] split = s.split(" "); //分割符操作
            if(split[0].equals("end")){
                break;
            }
            a = tranform.getsize(split);
            if(a==1){
                name = split[0];
                price = Integer.parseInt(split[1]);
                menu.addDish(name,price);
            }
            else if(a==2){
                id = Integer.parseInt(split[0]);
                name = split[1];
                portion = Integer.parseInt(split[2]);
                dishsum = Integer.parseInt(split[3]);
                Dish dish = menu.searthDish(name);
                if(dish==null){
                    System.out.println(name+" does not exist");
                }
                else{
                    System.out.println(id+" "+name+" "+dish.getprice(portion,dishsum));//输出单条订单的价格
                    order.addARecord(id,dish,portion,dishsum);//添加订单
                }
            }
            else if(a==3) {
                id = Integer.parseInt(split[0]);
                Record record = order.findRecordByNum(id);
                if (record == null) {
                    System.out.println("delete error");
                } else {
                    order.delARecordByOrderNum(id);
                }
            }
        }
        int sum=0;
        sum= order.getTotalPrice();   //计算总和
        System.out.println(sum);
    }
}

 

7-1 菜单计价程序-3

分数 40
作者 蔡轲
单位 南昌航空大学

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

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

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

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

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

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

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

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

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

删除记录格式:序号 delete

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

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

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

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

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

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

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

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

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

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

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

Dish {

String name;//菜品名称

int unit_price; //单价

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

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

Menu {

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

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

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

}

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

Record {

int orderNum;//序号\\

Dish d;//菜品\\

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

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

}

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

Order {

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

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

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

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

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

}

### 输入格式:

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

菜品记录格式:

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

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

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

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

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

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

### 输出格式:

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

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

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

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

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

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

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

输入格式:

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

菜品记录格式:

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

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

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

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

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

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

输出格式:

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

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

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

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

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

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

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

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 12/2/3
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end

输出样例:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 38

输入样例1:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 17/0/0
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end

输出样例1:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 22

输入样例2:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 16/59/59
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end

输出样例2:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1 out of opening hours

输入样例3:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/5 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
7 delete
end

输出样例3:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
delete error;
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
table 1 out of opening hours
table 2: 63

输入样例4:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/3 19/5/12
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 4 麻婆豆腐 1 1
7 delete
end

输出样例4:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
4 table 2 pay for table 1 12
delete error;
table 1: 63
table 2: 75

解题思路:相对前两次的菜单计价程序,这次的题目明显复杂许多,在菜单计价程序2的基础上,添加了桌号,和带点菜信息,并且饭店有固定的开放时间和对应的折扣,这里的内容其实是比较复杂的,最后我们也不再是输出单个的总价,而是要按照点菜的桌号顺序依次输出每一桌的总价。这里增加了一个新的类为Table类

Main函数流程为通过输入处理类获得输入类型

  • 输入菜品信息:得到此条信息的菜品类,查找该菜品是否已存在,若不存在则加入到Menu中,否则直接将基础单价改为当前单价即可
  • 输入点菜记录:同样对输入进行处理得到一个Order类,再判断合法性,查找是否存在当前菜品,根据相应结果给出相应输出
  • 输入删除记录:同理,不存在的删除序号输出相应信息
  • 代点菜记录:判断合法性后,将订单加入到点菜桌号,非法输出对应非法信息
  • 桌号标识:需要对时间进行处理,判断合法性以及时间段的合法

最后输出每个桌号的总价

  具体类体如下所示:

    

 

      具体代码和代码的质量分析如下:

package menu_2_1;

import java.util.Scanner;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;


class Dish {
    String name;//菜品名称
    int price; //单价
    public Dish(String name,int price){
        this.name = name;
        this.price = price;
    }
    public  int getprice(int portion,int dishsum){
        if(portion==1) {
            return price*dishsum;
        }
        else if(portion==2) {
            int Iprice = (int) (price*1.5);
            if(price-Iprice>=0.5){
                return (Iprice+1)*dishsum;
            }
            else {
                return Iprice*dishsum;
            }
        }
        else if(portion==3) {
            return price*2*dishsum;
        }
        return 0;
    }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份;
}

class Menu {
    Dish[] dishs = new Dish[100];

    public Dish searthDish(String dishName){
        for(int i=0;i<dishs.length;i++) {
            if(dishs[i]!=null && dishs[i].name.equals(dishName)) {
                return dishs[i];
            }
        }
        return null;
    }//根据菜名在菜谱中查找菜品信息,返回Dish对象。
    public Dish addDish(String dishName,int price){
        Dish dish = new Dish(dishName,price);
        for(int i=0;i<dishs.length;i++){
            if(dishs[i]==null){
                dishs[i] = dish;
                break;
            }
        }
        return dish;
    }
}

class Order {
    Record[] records = new Record[100];//保存订单上每一道的记录
    public int getTotalPrice() {
        int sum = 0;
        for(int i=0;i<records.length;i++) {
            if(records[i]!=null) {
                records[i].getPrice();
                sum+=records[i].getPrice();
            }
        }
        return sum;
    }
    public Record addARecord(int id, Dish dish, int portion, int dishsum){
        Record record = new Record(dish,portion,dishsum);
        records[id] = record;
        return record;
    }
    //添加一条菜品信息到订单中。
    public Record findRecordByNum(int id){
        return records[id];
    }
    public Record delARecordByOrderNum(int id){
        records[id]=null;
        return null;
    }
    public void dete(){
        for(int i=0;i<records.length;i++) {
            if(records[i]!=null) {
                records[i]=null;
            }
        }
    }
}

class Record {
    int dishsum;
    Dish d;//菜品
    int portion;//份额(1/2/3代表小/中/大份)
    public Record(Dish dish, int portion, int dishsum){
        this.dishsum = dishsum;
        this.d=dish;
        this.portion=portion;
    }
    int getPrice(){
        int price = d.getprice(portion,dishsum);
        return price;
    }//计价,计算本条记录的价格
}
class Tranform {
    public int getsize(String[] split) {
        String id = split[0]; String cd = split[1];String e=split[3];
        String[] arr = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
         if(id.equals("table"))
            return 4;
        for (int i = 0; i < 9; i++) {
            if (id.substring(0, 1).equals(arr[i])) {
                if (cd.equals("delete")) {
                    return 3;
                } 
                else {
                    for(int j=0;j<9;j++)
                        if(cd.substring(0, 1).equals(arr[i]))
                            return 5;
                     return 2;
                }
            }
        }
        return 1;
    }
}
class Table {
    int arr[] = new int[100];
    
    public void shuchu(){
        for(int i=0;i<arr.length;i++) {
            if(arr[i] ==-1) {
                System.out.println("table "+i+" out of opening hours");
            }
            else if(arr[i]!=0){
                System.out.println("table "+i+": "+arr[i]);
            }
        }
    }
}
public class Main {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        Menu menu = new Menu();
        Order order = new Order();
        Tranform tranform = new Tranform();
        Table table = new Table();
        Date date = new Date();
        String s;
        String name;
        int sum;
        int price;//单价
        int portion;//份额
        int id;//序号
        int a;
        int dishsum;//份数
        int tableid = 0; //桌号
        int lazy=0;//标记
        double zhekou=1.0;//折扣
        int help;//带点菜桌号
        while(true){
            s = input.nextLine();
            String[] split = s.split(" "); //分割符操作
            if(split[0].equals("end")){
                if(lazy>0){
                    if(zhekou==0){
                        table.arr[tableid]=-1;
                    }
                    else {
                        sum= order.getTotalPrice();
                        int sum_=(int)(sum*1.0*zhekou);
                        if(sum*1.0*zhekou-sum_>=0.5){
                            sum=sum_+1;
                        }
                        else{
                            sum=sum_;
                        }
                        table.arr[tableid] = sum;
                    }
                }
                break;
            }
            a = tranform.getsize(split);//System.out.println("a "+a);
            if(a==1){//菜品
                name = split[0];
                price = Integer.parseInt(split[1]);
                menu.addDish(name,price);
            }
            else if(a==4){//桌号
                lazy++;
                if(lazy>1){
                    sum= order.getTotalPrice();   //计算总和
                    if(zhekou==0){
                        table.arr[tableid]=-1;
                    }
                    else{
                        sum= order.getTotalPrice();
                        int sum_=(int)(sum*1.0*zhekou);
                        if(sum*1.0*zhekou-sum_>=0.5){
                            sum=sum_+1;
                        }
                        else{
                            sum=sum_;
                        }
                        table.arr[tableid] = sum;
                    }
                    order.dete();
                }
                tableid = Integer.parseInt(split[1]);
                zhekou=date.dateToWeek(split[2]);
                zhekou= date.dateToday(split[3],zhekou);
                System.out.println("table "+tableid+":");
            }
            else if(a==5){//代点菜
                help= Integer.parseInt(split[0]);
                id = Integer.parseInt(split[1]);
                name = split[2];
                portion = Integer.parseInt(split[3]);
                dishsum = Integer.parseInt(split[4]);
                Dish dish = menu.searthDish(name);
                if(dish==null){
                    System.out.println(name+" does not exist");
                }
                else{
                    System.out.println(id+" table "+tableid+" pay for table "+help+" "+dish.getprice(portion,dishsum));//输出单条订单的价格//这里是带点菜不输出
                    order.addARecord(id,dish,portion,dishsum);//添加订单
                }
            }
            else if(a==2){//点菜记录
                id = Integer.parseInt(split[0]);
                name = split[1];
                portion = Integer.parseInt(split[2]);
                dishsum = Integer.parseInt(split[3]);
                Dish dish = menu.searthDish(name);
                if(dish==null){
                    System.out.println(name+" does not exist");
                }
                else{
                    System.out.println(id+" "+name+" "+dish.getprice(portion,dishsum));//输出单条订单的价格
                    order.addARecord(id,dish,portion,dishsum);//添加订单
                }
            }
            else if(a==3) {//删除订单
                id = Integer.parseInt(split[0]);
                Record record = order.findRecordByNum(id);
                if (record == null) {
                    System.out.println("delete error");
                } else {
                    order.delARecordByOrderNum(id);
                }
            }
        }
        table.shuchu();
    }
}

class Date{
    public double dateToWeek(String datetime) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");
        int[] weekDays = {7,6,5,4,3,2,1};
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        java.util.Date datet = null;
        try {
            datet = f.parse(datetime);
            cal.setTime(datet);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        if(weekDays[w]>5){
            return 1.0;
        }
        return 0.8;
    }
    public double dateToday(String daytime,double zhekou){
        String[] split = daytime.split("/");
        int p= Integer.parseInt(split[0]);
        int p1= Integer.parseInt(split[1]);
        int p2= Integer.parseInt(split[2]);
        if(zhekou==1.0){
            if(p==9){
                if(p1>=30){
                    return zhekou*1.0;
                }
                return 0;
            }
            else if(p==21){
                if(p1<=29){
                    return 1.0*zhekou;
                }
                else if(p1==30){
                    if(p2==0){
                        return 1.0*zhekou;
                    }
                    return 0;
                }
                return 0;
            }
            else if(p2>=10 && p<=20){
                return 1.0*zhekou;
            }
            return 0;
        }
        else if(zhekou==0.8){
            if(p==20){
                if(p1<=29){
                    return 1.0*zhekou;
                }
                else if(p1==30){
                    if(p2==0){
                        return 1.0*zhekou;
                    }
                    return 0;
                }
                return 0;
            }
            else if(p>=17 && p<=19){
                return 1.0*zhekou;
            }
            if(p==10){
                if(p1>=30){
                    return zhekou*0.75;
                }
                return 0;
            }
            else if(p==14){
                if(p1<=29){
                    return 0.75*zhekou;
                }
                else if(p1==30){
                    if(p2==0){
                        return 0.75*zhekou;
                    }
                    return 0;
                }
                return 0;
            }
            else if(p2>=9 && p<=13){
                return 0.75*zhekou;
            }
            return 0;
        }
        return 0;
    }
}

 

 第五次题目集

7-1 菜单计价程序-4

本次课题比菜单计价系列-3增加的异常情况:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

例如:麻婆豆腐 9 T

菜价的计算方法:

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

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

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

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

输入格式:

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

菜品记录格式:

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

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

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

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

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

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

输出格式:

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

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

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

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

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

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

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 1 2
2 delete
2 delete
end

输出样例:

在这里给出相应的输出。例如:

table 31: 
1 num out of range 16
2 油淋生菜 18
deduplication 2
table 31: 0 0

输入样例1:

份数超出范围+份额超出范围。例如:

麻婆豆腐 12
油淋生菜 9 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 4 2
end

输出样例1:

份数超出范围+份额超出范围。例如:

table 31: 
1 num out of range 16
2 portion out of range 4
table 31: 0 0

输入样例2:

桌号信息错误。例如:

麻婆豆腐 12
油淋生菜 9 T
table a 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例2:

在这里给出相应的输出。例如:

wrong format

输入样例3:

混合错误:桌号信息格式错误+混合的菜谱信息(菜谱信息忽略)。例如:

麻婆豆腐 12
油淋生菜 9 T
table 55 2023/3/31 12/000/00
麻辣香锅 15
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例3:

在这里给出相应的输出。例如:

wrong format

输入样例4:

错误的菜谱记录。例如:

麻婆豆腐 12.0
油淋生菜 9 T
table 55 2023/3/31 12/00/00
麻辣香锅 15
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例4:

在这里给出相应的输出。例如:

wrong format
table 55: 
invalid dish
麻婆豆腐 does not exist
2 油淋生菜 14
table 55: 14 10

输入样例5:

桌号格式错误(以“table”开头)+订单格式错误(忽略)。例如:

麻婆豆腐 12
油淋生菜 9 T
table a 2023/3/15 12/00/00
1 麻婆 豆腐 1 1
2 油淋生菜 2 1
end

输出样例5:

在这里给出相应的输出。例如:

wrong format

输入样例6:

桌号格式错误,不以“table”开头。例如:

麻婆豆腐 12
油淋生菜 9 T
table 1 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
tab le 2 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例6:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 12
2 油淋生菜 14
wrong format
record serial number sequence error
record serial number sequence error
table 1: 26 17

 

解题思路:本次在菜单3的基础上增加了异常处理,同时增加了输入异常判断类InputAddress类,对异常值进行判断,异常情况有点多,很多测试点没过,真的真的很麻烦很麻烦,头大

通过输入处理类获得输入类型

  • 输入菜品信息:得到此条信息的菜品类,查找该菜品是否已存在,若不存在则加入到Menu中,否则直接将基础单价改为当前单价即可
  • 输入点菜记录:同样对输入进行处理得到一个Order类,再判断合法性,查找是否存在当前菜品,根据相应结果给出相应输出
  • 输入删除记录:同理,不存在的删除序号输出相应信息
  • 代点菜记录:判断合法性后,将订单加入到点菜桌号,非法输出对应非法信息
  • 桌号标识:需要对时间进行处理,判断合法性以及时间段的合法

增加对各种异常输入以及不合法的情况的处理,输出对应提示信息

最后输出每个桌号的总价以及折后价

具体类体如下所示:

 

具体代码和代码的质量分析如下:

 
import java.text.ParseException;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Scanner;
 
public class Main {
    public static boolean isNumeric(String string) {
        int intValue;
        try {
            intValue = Integer.parseInt(string);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
 
    public static void main(String[] args) throws ParseException {
        Menu menu = new Menu();
        ArrayList<Table> tables = new ArrayList<Table>();
        Scanner input = new Scanner(System.in);
        String str1 = new String();
        int i = 0;
        int portion = 0, quota = 0;
        while (true) {// 输入菜单
            Dish temp = new Dish();
            int isRepeat = -1;
            str1 = input.nextLine();
            if (str1.matches("[\\S]* [1-9][\\d]*")) {
                String[] token = str1.split(" ");
                temp.name = token[0];
                temp.unit_price = Integer.parseInt(token[1]);
                if (temp.unit_price > 300) {
                    System.out.println(temp.name + " price out of range " + temp.unit_price);
                    continue;
                }
                temp.isT = false;
                isRepeat = menu.searchDish(temp.name);
                if (isRepeat != -1) {
                    menu.dishs.remove(isRepeat);
                }
                menu.dishs.add(temp);
            } else if (str1.matches("[\\S]* [\\d]* T")) {
                String[] token = str1.split(" ");
                temp.name = token[0];
                temp.unit_price = Integer.parseInt(token[1]);
                if (temp.unit_price > 300) {
                    System.out.println(temp.name + " price out of range " + temp.unit_price);
                    continue;
                }
                temp.isT = true;
                if (isRepeat != -1) {
                    menu.dishs.remove(isRepeat);
                }
                menu.dishs.add(temp);
            } else if (str1.equals("end")) {
                break;
            } else if (str1.matches("tab.*")) {
                break;
 
            } else {
                System.out.println("wrong format");
                continue;
            }
        }
        while (!str1.equals("end")) {
            Table temp = new Table();
            boolean isRepeat = false;
            int repeatNum = 0;
            if (str1.matches("table.*")) {
                if (str1.matches("table [1-9][\\d]* [\\d]*/[\\d][\\d]?/[\\d][\\d]? [\\d][\\d]?/[\\d][\\d]?/[\\d][\\d]?")) {
                    String[] token = str1.split(" ");
                    String[] Date = token[2].split("/");
                    String[] Time = token[3].split("/");
                    int[] intDate = new int[3];
                    int[] intTime = new int[3];
                    for (i = 0; i < 3; i++) {
                        intDate[i] = Integer.parseInt(Date[i]);
                        intTime[i] = Integer.parseInt(Time[i]);
                    }
                    temp.num = Integer.parseInt(token[1]);
                    if (temp.num > 55) {
                        System.out.println(temp.num + " table num out of range");
                        str1 = input.nextLine();
                        continue;
 
                    }
                    try {
                        temp.time = LocalDateTime.of(intDate[0], intDate[1], intDate[2], intTime[0], intTime[1],
                                intTime[2]);
                        temp.getWeekDay();
                    } catch (DateTimeException e) {
                        System.out.println(temp.num + " date error");
                        str1 = input.nextLine();
                        continue;
                    }
                    if (!(temp.time.isAfter(LocalDateTime.of(2022, 1, 1, 0, 0, 0))
                            && temp.time.isBefore(LocalDateTime.of(2024, 1, 1, 0, 0, 0)))) {
                        System.out.println("not a valid time period");
                        str1 = input.nextLine();
                        continue;
                    }
                    // 判断桌号是否重复
                    if (temp.isOpen()) {
                        for (i = 0; i < tables.size(); i++) {
                            // 有重复的桌号
                            if (temp.num == tables.get(i).num && tables.get(i).isOpen()) {
                                Duration duration = Duration.between(temp.time, tables.get(i).time);
                                // 同一天
                                if (duration.toDays() == 0) {
                                    // 在周一到周五
                                    if (temp.weekday > 0 && temp.weekday < 6) {
                                        // 在同一时间段
                                        if (temp.time.getHour() < 15 && tables.get(i).time.getHour() < 15) {
                                            temp = tables.get(i);
                                            isRepeat = true;
                                            repeatNum = i;
                                            break;
                                        }
                                    }
                                    // 在周末
                                    else {
                                        // 时间相差小于一小时
                                        if (duration.toHours() < 3600) {
                                            temp = tables.get(i);
                                            repeatNum = i;
                                            isRepeat = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if(!isRepeat) {
                        System.out.println("table " + temp.num + ": ");
                    }
                    
                }
                else {
                    System.out.println("wrong format");
                    str1 = input.nextLine();
                    continue;
                }
                // 本桌开始点菜
                while (true) {
                    str1 = input.nextLine();
                    if (str1.matches("[1-9][\\d]* [\\S]* [\\d] [1-9][\\d]*")) {
                        String[] token = str1.split(" ");
                        portion = Integer.parseInt(token[2]);
                        quota = Integer.parseInt(token[3]);
                        if (temp.order.records.size() > 0) {
                            if (Integer.parseInt(
                                    token[0]) <= temp.order.records.get(temp.order.records.size() - 1).orderNum) {
                                System.out.println("record serial number sequence error");
                                continue;
                            }
                        }
                        if (menu.searchDish(token[1]) == -1) {
                            System.out.println(token[1] + " does not exist");
                            continue;
                        }
                        if (portion > 3 || portion < 1) {
                            System.out.println(Integer.parseInt(token[0]) + " portion out of range " + portion);
                            continue;
                        }
                        if (quota > 15) {
                            System.out.println(Integer.parseInt(token[0]) + " num out of range " + quota);
                            continue;
                        }
                        temp.od(menu, token[0], token[1], portion, quota);
                    }
                    // 判断是否为删除订单
                    else if (str1.matches("[1-9][\\d]* delete")) {
                        String[] token = str1.split(" ");
                        temp.order.delARecordByOrderNum(Integer.parseInt(token[0]));
                    }
                    // 判断是否为夹杂菜单
                    else if (str1.matches("[\\S]* [\\d]*")) {
                        System.out.println("invalid dish");
                        continue;
                    } else if (str1.matches("[\\S]* [\\d]* T")) {
                        System.out.println("invalid dish");
                        continue;
                    }
                    // 判断是否为代点
                    else if (str1.matches("[\\d]* [\\d]* [\\S]* [\\d] [1-9][\\d]*")) {
                        String[] token = str1.split(" ");
                        // 判断代点桌号是否存在
                        boolean exist = false;
                        for (int j = 0; j < tables.size(); j++) {
                            if (tables.get(j).num == Integer.parseInt(token[0])) {
                                exist = true;
                                break;
                            }
                        }
                        if (exist) {
                            System.out.print(Integer.parseInt(token[1]) + " table " + temp.num + " pay for table "
                                    + Integer.parseInt(token[0]) + " ");
                            Record treat = new Record();
                            treat.d = menu.dishs.get(menu.searchDish(token[2]));
                            portion = Integer.parseInt(token[3]);
                            quota = Integer.parseInt(token[4]);
                            treat.portion = portion;
                            treat.quota = quota;
                            System.out.print(treat.getPrice() + "\n");
                            temp.sum += treat.getPrice();
                        }
                        // 若不存在则输出内容
                        else {
                            System.out.println("Table number :" + Integer.parseInt(token[0]) + " does not exist");
                        }
 
                    } else if (str1.equals("end")) {
                        break;
                    } else if(str1.matches("ta.*")){
                        break;
                        
                    }
                    else {
                        System.out.println("wrong format");
                        continue;
                    }
                }
            } else if (str1.matches("t.*")) {
                isRepeat = true;
                temp = tables.get(tables.size());
                while (true) {
                    str1 = input.nextLine();
                    if (str1.matches("[1-9][\\d]* [\\S]* [\\d] [1-9][\\d]*")) {
                        String[] token = str1.split(" ");
                        portion = Integer.parseInt(token[2]);
                        quota = Integer.parseInt(token[3]);
                        // 判断订单号是否由小到大排列
                        if (temp.order.records.size() > 0) {
                            if (Integer.parseInt(
                                    token[0]) <= temp.order.records.get(temp.order.records.size() - 1).orderNum) {
                                System.out.println("record serial number sequence error");
                                continue;
                            }
                        }
                        if (menu.searchDish(token[1]) == -1) {
                            System.out.println(token[1] + " does not exist");
                            continue;
                        }
                        if (portion > 3 || portion < 1) {
                            System.out.println(Integer.parseInt(token[0]) + " portion out of range " + portion);
                            continue;
                        }
                        if (quota > 15) {
                            System.out.println(Integer.parseInt(token[0]) + " num out of range " + quota);
                            continue;
                        }
                        temp.od(menu, token[0], token[1], portion, quota);
                    }
                    // 判断是否为删除订单
                    else if (str1.matches("[1-9][\\d]* delete")) {
                        String[] token = str1.split(" ");
                        temp.order.delARecordByOrderNum(Integer.parseInt(token[0]));
                    }
                    // 判断是否为夹杂菜单
                    else if (str1.matches("[\\S]* [\\d]*")) {
                        System.out.println("invalid dish");
                        continue;
                    } else if (str1.matches("[\\S]* [\\d]* T")) {
                        System.out.println("invalid dish");
                        continue;
                    }
                    // 判断是否为代点
                    else if (str1.matches("[\\d]* [\\d]* [\\S]* [\\d] [1-9][\\d]*")) {
                        String[] token = str1.split(" ");
                        // 判断代点桌号是否存在
                        boolean exist = false;
                        for (int j = 0; j < tables.size(); j++) {
                            if (tables.get(j).num == Integer.parseInt(token[0])) {
                                exist = true;
                                break;
                            }
                        }
                        if (exist) {
                            System.out.print(Integer.parseInt(token[1]) + " table " + temp.num + " pay for table "
                                    + Integer.parseInt(token[0]) + " ");
                            Record treat = new Record();
                            treat.d = menu.dishs.get(menu.searchDish(token[2]));
                            portion = Integer.parseInt(token[3]);
                            quota = Integer.parseInt(token[4]);
                            treat.portion = portion;
                            treat.quota = quota;
                            System.out.print(treat.getPrice() + "\n");
                            temp.sum += treat.getPrice();
                        }
                        // 若不存在则输出内容
                        else {
                            System.out.println("Table number :" + Integer.parseInt(token[0]) + " does not exist");
                        }
 
                    } else if (str1.equals("end")) {
                        break;
                    } else {
                        System.out.println("wrong format");
                        continue;
                    }
                }
                if (tables.size() != 0) {
                    tables.get(tables.size() - 1).order.records.addAll(temp.order.records);
                }
            } else {
                str1 = input.nextLine();
                continue;
            }
 
            // 本桌点菜结束,进入下一桌
            if (isRepeat) {
                tables.remove(repeatNum);
            }
            temp.getSum();
            tables.add(temp);
        }
        // 最终输出桌号订单信息
        for (i = 0; i < tables.size(); i++) {
            if (tables.get(i).isOpen()) {
                System.out
                        .println("table " + tables.get(i).num + ": " + tables.get(i).origSum + " " + tables.get(i).sum);
            } else
                System.out.println("table " + tables.get(i).num + " out of opening hours");
        }
    }
 
    static class Dish {
        String name;
        int unit_price;
        boolean isT = false;
    }
 
    static class Record {
        int orderNum;
        Dish d;
        int portion;
        int quota;
        boolean isDeleted = false;
 
        int getPrice() {
            if (portion == 2)
                return (int) Math.round(1.5 * d.unit_price) * quota;
            else if (portion == 3)
                return 2 * d.unit_price * quota;
            else
                return d.unit_price * quota;
        }
    }
 
    static class Menu {
        ArrayList<Dish> dishs = new ArrayList<Dish>();
 
        int searchDish(String dishName) {
            for (int i = 0; i < dishs.size(); i++) {
                if (dishName.equals(dishs.get(i).name)) {
                    return i;
                }
            }
            return -1;
        }
 
        Dish addDish(String dishName, int unit_price) {
            Dish newDish = new Dish();
            newDish.name = dishName;
            newDish.unit_price = unit_price;
            return newDish;
        }
    }
 
    static class Order {
//        Record[] records = new Record[20];
        ArrayList<Record> records = new ArrayList<Record>();
 
        Record addARecord(int orderNum, String dishName, int portion, int quota, Menu menu) {
            Record newRecord = new Record();
            newRecord.orderNum = orderNum;
            newRecord.d = menu.dishs.get(menu.searchDish(dishName));
            newRecord.portion = portion;
            newRecord.quota = quota;
            System.out.println(newRecord.orderNum + " " + newRecord.d.name + " " + newRecord.getPrice());
            return newRecord;
        }
 
        int searchReocrd(String name) {
            for (int i = 0; i < records.size(); i++) {
                if (records.get(i).d.name == name) {
                    return i;
                }
            }
            return -1;
        }
 
        boolean delARecordByOrderNum(int orderNum) {
            int i = 0, flag = 0;
            for (i = 0; i < records.size(); i++) {
                if (records.get(i).orderNum == orderNum) {
                    if (records.get(i).isDeleted == false) {
                        records.get(i).isDeleted = true;
                    } else {
                        System.out.println("deduplication " + orderNum);
                    }
                    flag++;
                }
            }
            if (flag == 0) {
                System.out.println("delete error;");
                return false;
            }
            return true;
        }
    }
 
    static class Table {
        Order order = new Order();
        int num;
        LocalDateTime time;
        int weekday;
        long sum = 0;
        long origSum = 0;
        void od(Menu menu, String str1, String str2, int portion, int quota) {
            {
                order.records.add(order.addARecord(Integer.parseInt(str1), str2, portion, quota, menu));
 
            }
        }
 
        void getWeekDay() {
            weekday = time.getDayOfWeek().getValue();
        }
 
        void getSum() {
            for (int i = 0; i < order.records.size(); i++) {
                if (!order.records.get(i).isDeleted) {
                    origSum += order.records.get(i).getPrice();
                    if (order.records.get(i).d.isT) {
                        if (weekday > 0 && weekday < 6) {
                            sum += Math.round(order.records.get(i).getPrice() * 0.7);
                        } 
                        else {
                            sum += order.records.get(i).getPrice();
                        }
                    }
                    else 
                    {
                        if (weekday > 0 && weekday < 6) {
                            if (time.getHour() >= 17 && time.getHour() < 20)
                                sum += Math.round(order.records.get(i).getPrice() * 0.8);
                            if (time.getHour() == 20) {
                                if (time.getMinute() <= 30)
                                    sum += Math.round(order.records.get(i).getPrice() * 0.8);
                            }
                            if (time.getHour() >= 10 && time.getHour() < 14)
                                sum += Math.round(order.records.get(i).getPrice() * 0.6);
                            if (time.getHour() == 14) {
                                if (time.getMinute() <= 30)
                                    sum += Math.round(order.records.get(i).getPrice() * 0.6);
                            }
                        }
                        else sum+=order.records.get(i).getPrice();
                    }
                }
            }
 
        }
 
        boolean isOpen() {
            if (weekday > 0 && weekday < 6) {
                if (time.getHour() >= 17 && time.getHour() < 20)
                    return true;
                if (time.getHour() == 20) {
                    if (time.getMinute() <= 30)
                        return true;
                }
                if (time.getHour() > 10 && time.getHour() < 14)
                    return true;
                if (time.getHour() == 10) {
                    if (time.getMinute() >= 30)
                        return true;
                }
                if (time.getHour() == 14) {
                    if (time.getMinute() <= 30)
                        return true;
                }
            } else {
                if (time.getHour() > 9 && time.getHour() < 21)
                    return true;
                if (time.getHour() == 9) {
                    if (time.getMinute() >= 30)
                        return true;
                }
                if (time.getHour() == 21) {
                    if (time.getMinute() <= 30)
                        return true;
                }
            }
            return false;
 
        }
    }
}

 

第六次题目集

 7-1 菜单计价程序-5

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

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

例如:麻婆豆腐 川菜 9 T

菜价的计算方法:

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

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

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

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

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

例如:麻婆豆腐 川菜 9 T

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

例如:1 麻婆豆腐 4 1 9

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

acidity num out of range : 5

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

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

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

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

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

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

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

 

 

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

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

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

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

输出结果时,先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。不考虑各桌时间段的问题,同一个客户的所有table金额都要累加。

输出用户支付金额格式:

用户姓名+英文空格+手机号+英文空格+支付金额

 

 

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

 

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

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

输入格式:

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

 

菜品记录格式:

 

菜名+口味类型+英文空格+基础价格

 

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

 

点菜记录格式:序号+英文空格+菜名+英文空格+辣/酸/甜度值+英文空格+份额+英文空格+份数 注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。辣/酸/甜度取值范围见题目中说明。

 

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

 

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称**+英文空格+辣/酸/甜度值+**英文空格+份额+英文空格+分数

 

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

输出格式:

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

 

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

 

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

 

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

 

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

 

之后按输入顺序一次输出每一桌所有菜品的价格(整数数值),

格式:table+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格

 

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

输入样例1:

桌号时间超出营业范围。例如:

麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 21/30/00
1 麻婆豆腐 3 1 2
2 油淋生菜 2 1
3 麻婆豆腐 2 3 2
end

输出样例1:

在这里给出相应的输出。例如:

table 1 out of opening hours

输入样例2:

一种口味的菜品。例如:

麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 20/30/00
1 麻婆豆腐 2 1 2
2 油淋生菜 2 1
3 麻婆豆腐 2 3 2
end

输出样例2:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 24
2 油淋生菜 14
3 麻婆豆腐 48
table 1: 86 62 川菜 4 稍辣
tom 13605054400 62

 

输入样例3:

辣度值超出范围。例如:

麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 18/30/00
1 麻婆豆腐 6 1 2
2 油淋生菜 1 1
3 麻婆豆腐 5 3 2
end

输出样例3:

在这里给出相应的输出。例如:

table 1: 
spicy num out of range :6
2 油淋生菜 9
3 麻婆豆腐 48
table 1: 57 41 川菜 2 爆辣
tom 13605054400 41

输入样例4:

同一用户对应多桌菜。例如:

麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 18/30/00
1 麻婆豆腐 1 1 2
2 油淋生菜 1 1
3 麻婆豆腐 2 2 2
table 2 : tom 13605054400 2023/5/6 18/30/00
1 麻婆豆腐 2 1 2
2 麻辣鸡丝 2 2
3 麻婆豆腐 2 1 1
end

输出样例4:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 24
2 油淋生菜 9
3 麻婆豆腐 36
table 2: 
1 麻婆豆腐 24
2 麻辣鸡丝 30
3 麻婆豆腐 12
table 1: 69 49 川菜 4 稍辣
table 2: 66 66 川菜 3 稍辣
tom 13605054400 115

输入样例5:

多用户多桌菜。例如:

东坡肉 浙菜 25 T
油淋生菜 9
蜜汁灌藕 浙菜 10 T
刀削面 晋菜 10 T
醋浇羊肉 晋菜 30 T
麻婆豆腐 川菜 12 T
麻辣鸡丝 川菜 15 T
table 1 : tom 13605054400 2023/5/6 12/30/00
1 醋浇羊肉 4 1 1
3 刀削面 1 1 3
2 东坡肉 3 2 1
4 麻辣鸡丝 2 1 1
table 2 : jerry 18100334566 2023/5/1 12/30/00
1 醋浇羊肉 1 1 2
3 麻婆豆腐 2 2 1
4 麻辣鸡丝 2 3 3
table 3 : jerry 18100334566 2023/5/1 12/30/00
1 醋浇羊肉 2 1 1
3 蜜汁灌藕 1 1 2
2 东坡肉 2 2 1
4 麻辣鸡丝 5 1 1
end

输出样例5:

在这里给出相应的输出。例如:

table 1: 
1 醋浇羊肉 30
3 刀削面 30
2 东坡肉 38
4 麻辣鸡丝 15
table 2: 
1 醋浇羊肉 60
3 麻婆豆腐 18
4 麻辣鸡丝 90
table 3: 
1 醋浇羊肉 30
3 蜜汁灌藕 20
2 东坡肉 38
4 麻辣鸡丝 15
table 1: 113 113 川菜 1 稍辣 晋菜 4 稍酸 浙菜 1 甜
table 2: 168 118 川菜 4 稍辣 晋菜 2 微酸
table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜
jerry 18100334566 191
tom 13605054400 113

输入样例6:

多用户多桌菜含代点菜。例如:

东坡肉 浙菜 25 T
油淋生菜 9
蜜汁灌藕 浙菜 10 T
刀削面 晋菜 10 T
醋浇羊肉 晋菜 30 T
麻婆豆腐 川菜 12 T
麻辣鸡丝 川菜 15 T
table 1 : tom 13605054400 2023/5/6 12/30/00
1 醋浇羊肉 4 1 1
3 刀削面 1 1 3
2 东坡肉 3 2 1
4 麻辣鸡丝 2 1 1
table 2 : jerry 18100334566 2023/5/1 12/30/00
1 1 醋浇羊肉 0 1 2
3 麻婆豆腐 2 2 1
4 麻辣鸡丝 2 3 3
table 3 : lucy 18957348763 2023/5/1 12/30/00
1 醋浇羊肉 2 1 1
3 蜜汁灌藕 1 1 2
2 东坡肉 2 2 1
4 麻辣鸡丝 5 1 1
end

输出样例6:

在这里给出相应的输出。例如:

table 1: 
1 醋浇羊肉 30
3 刀削面 30
2 东坡肉 38
4 麻辣鸡丝 15
table 2: 
1 table 2 pay for table 1 60
3 麻婆豆腐 18
4 麻辣鸡丝 90
table 3: 
1 醋浇羊肉 30
3 蜜汁灌藕 20
2 东坡肉 38
4 麻辣鸡丝 15
table 1: 113 113 川菜 1 稍辣 晋菜 6 微酸 浙菜 1 甜
table 2: 168 118 川菜 4 稍辣
table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜
jerry 18100334566 118
lucy 18957348763 73
tom 13605054400 113

输入样例7:

错误的菜品记录和桌号记录,用户丢弃。例如:

东坡肉 25 T
油淋生菜 9
table 1 : tom 136050540 2023/5/1 12/30/00
2 东坡肉 3 2 1
end

输出样例7:

在这里给出相应的输出。例如:

wrong format
wrong format
代码长度限制
50 KB
时间限制
1000 ms
内存限制
64 MB
 
解题思路:本题在菜单3的基础上增加特色菜和客户订多桌菜的情况,本题对菜单3的架构进行了调整,增加了客户类,虽然调了很久,但测试点很多没有通过,还是自己写代码能力不太行吧~。

类结构增加一个Custom类,记录客户的信息

  • Table类:包括桌号、点菜时间、点菜记录
  • Menu类:属性包括一个菜品数组,用来存储菜品类
  • Dish类:属性包括菜品名称和单价,描述菜品信息
  • Order类:存储点菜记录的信息
  • Record类:包括四个属性:点菜序号、菜品、份额、份数
  • Custom类:属性包括:客户姓名、客户电话、客户点的桌号
具体类体如下所示:

 

具体代码和代码的质量分析如下:
  1 import java.text.ParseException;
  2 import java.text.SimpleDateFormat;
  3 import java.util.*;
  4 public class Main {
  5     public static void main(String[] args) throws ParseException {
  6         Scanner input = new Scanner(System.in);
  7         int i, t = 0, year, month, day, shi, fen, miao, f = 0, y = -1;
  8         String a = null;
  9         Menu menu = new Menu();
 10         Table[] tables = new Table[10];
 11         for (i = 0; ; i++) {
 12             if(f==1)
 13                 break;
 14             if (y == -1)
 15                 a = input.nextLine();
 16             if (a.equals("end"))
 17                 break;
 18             String[] s = a.split(" ");
 19             int x = s.length;
 20             if (x <= 3 && t == 0) {//菜品
 21                 int l = 0;
 22                 int n = 0;
 23                 if (!s[1].matches("[1-9]||[1-9][0-9]||[1-2][0-9][0-9]")) {
 24                     System.out.println("wrong format");
 25                     menu.dishs[menu.t] = new Dish();
 26                 } else {
 27                     n = Integer.parseInt(s[1]);
 28                     boolean special = false;
 29                     if (x == 3) {
 30                         if(s[2].matches("T"))
 31                         special = true;
 32                        else{
 33                            System.out.println("wrong format");
 34                     System.exit(0);
 35                        }
 36                     }
 37                     menu.addDish(s[0], n, special);
 38                     if (n <= 0 || n >= 300) {//菜价超出范围
 39                         System.out.println(s[0] + " price out of range " + n);
 40                     }
 41                 }
 42             } else {
 43 
 44                 t = 1;
 45                 if(x>4){
 46                     System.out.println("wrong format");
 47                     System.exit(0);
 48                 }
 49                 while (true) {
 50                     if(f==1)
 51                         break;
 52                     y++;
 53                     if (x == 4 && !(s[0].matches("table")) && y == 0) {//第一个
 54                         System.out.println("wrong format");
 55                         System.exit(0);
 56                     }
 57                     while ((x == 4 && s[0].matches("table")) || y > 0) {
 58                         if(f==1)
 59                             break;
 60                         if (s.length == 4) {////后面的桌子直接进入点菜,后面所有的信息并入上一桌一起计算
 61                             tables[y] = new Table();
 62                             tables[y].order = new Order();
 63                             String[] s1 = s[2].split("/");//年月日的分割
 64                             String[] s2 = s[3].split("/");//时分秒的分割
 65                             SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd");
 66                             SimpleDateFormat d2 = new SimpleDateFormat("u");
 67                             Date date = d.parse(s1[0] + "-" + s1[1] + "-" + s1[2]);//日期格式化
 68                             int week = Integer.parseInt(d2.format(date));//提取星期几
 69                             tables[y].week = week;
 70                             if (!s[1].matches("\\d*")) {//检查"table"部分
 71                                 System.out.println("wrong format");
 72                                 if (y == 0)//第一个桌子桌号错误直接退出
 73                                     System.exit(0);
 74                                 else//后面所有的信息并入上一桌一起计算
 75                                     y--;
 76                             } else {
 77                                 tables[y].num = Integer.parseInt(s[1]);
 78                                 tables[y].year = Integer.parseInt(s1[0]);
 79                                 tables[y].month = Integer.parseInt(s1[1]);
 80                                 tables[y].day = Integer.parseInt(s1[2]);
 81                                 tables[y].shi = Integer.parseInt(s2[0]);
 82                                 tables[y].fen = Integer.parseInt(s2[1]);
 83                                 tables[y].miao = Integer.parseInt(s2[2]);
 84                                 if(s[1].matches("[0].+")){
 85                                     System.out.println("wrong format");
 86                                     System.exit(0);
 87                                 }
 88 
 89                                 if (!(tables[y].num <= 55 && tables[y].num >= 1)) {
 90                                     System.out.println("table num out of range");
 91                                     System.exit(0);
 92                                 }
 93                                 else if(!tables[y].check()){
 94                                     System.out.println(tables[y].num+" date error");
 95                                     System.exit(0);
 96                                 }
 97                                 else if(tables[y].year>2023||tables[y].year<2022){
 98                                     System.out.println("not a valid time period");
 99                                     System.exit(0);
100                                 }
101                                 else
102                                     System.out.println("table " + Integer.parseInt(s[1]) + ": ");
103                             }
104                         } else {
105                             System.out.println("wrong format");
106                             f = 0;
107                             y--;//数据并入上一卓
108                         }
109                         for (; ; i++) {//点菜
110                             if (f == 1 || f == 2)
111                                 break;
112                             String aa = input.nextLine();
113                             String[] ss = aa.split(" ");
114                             //System.out.println(y + "---------" + aa);
115                             if (ss.length == 4 && ss[0].charAt(0) == 't') {//新桌子
116                                 s = ss;
117                                 y++;
118                                 break;
119                             }
120                             if (ss.length == 4) {//点菜
121                                 //System.out.println(y+"%"+ss[0]);
122                                 //tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
123                                 if (!tables[y].checkorder(Integer.parseInt(ss[0])))//检查订单序号顺序
124                                     System.out.println("record serial number sequence error");
125                                 else if (menu.searthDish(ss[1])==null)//订单的菜不存在
126                                     System.out.println(ss[1] + " does not exist");
127                                 else if (Integer.parseInt(ss[2]) > 3) {//份额超过3
128                                     System.out.println(ss[0] + " " + "portion out of range" + " " + ss[2]);
129                                 } else if (Integer.parseInt(ss[3]) > 15) {//订单大于15
130                                     System.out.println(ss[0] + " " + "num out of range" + " " + ss[3]);
131                                 } else {
132                                     tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
133                                     System.out.println(ss[0] + " " + ss[1] + " " + tables[y].order.records[tables[y].order.s - 1].ygetPrice());
134                                     tables[y].order.records[tables[y].order.s - 1].shi=tables[y].shi;
135                                     tables[y].order.records[tables[y].order.s - 1].fen=tables[y].fen;
136                                     
137                                 }
138                             }
139                             if (ss.length == 2 && ss[1].matches("delete")) {//删除
140                                 if(tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))==-1) {
141                                     System.out.println("delete error");
142                                 }
143                                 else {
144 
145                                     tables[y].order.delARecordByOrderNum(Integer.parseInt(ss[0]));
146                                     if (tables[y].order.records[tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))].life == 2) //重复删除的情况
147                                         System.out.println("deduplication " + ss[0]);
148                                 }
149                             }
150                             if ((ss.length == 2 || ss.length == 3) && !ss[1].matches("delete")) {
151                                 System.out.println("invalid dish");
152                             }
153                             if (ss.length > 4) {
154                                 a = aa;
155                                 s = a.split(" ");
156 
157                                 f = 2;
158 
159                             }
160                            // System.out.println("////");
161                         /*if(ss.length==5){//代点菜
162                             for(int t=0;t<=y;t++){
163                                 if(ss[0].equals(tables[i].num))
164                             }
165                         }*/
166                             if (aa.equals("end")) {
167                                 f = 1;
168                                 break;
169                             }
170 
171                         }
172                         if (f == 1 || f == 2)
173                             break;
174                     }
175                     if (f == 1)
176                         break;
177                 }
178             }
179             }
180             for (i = 0; i <= y; i++) {
181                 System.out.println("table " + tables[i].num + ": " + tables[i].order.ygetTotalPrice() + " " + tables[i].order.getTotalPrice());
182             }
183     }
184 }
185 
186     class Dish {
187 
188         String name;//菜品名称
189 
190         int unit_price; //单价
191         int life=0;//
192         boolean special = false;
193         public Dish(){
194 
195         }
196         public Dish(String name,int unit_price,boolean special){
197             this.name = name;
198             this.unit_price = unit_price;
199             this.special = special;
200         }
201 
202         int getPrice(int portion){
203             int s = 0;
204             if(portion==1)
205                 s = unit_price*1;
206             if (portion==2)
207                 s = (int) Math.round(unit_price*1.5);
208             if(portion==3)
209                 s = unit_price*2;
210             return s;
211         }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
212     }
213     class Menu {
214 
215         Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息
216         int t=0;
217         public Menu(){
218 
219         }
220         Dish searthDish(String dishName) {
221             for (int i = 0;i < t; i++) {
222                 if (dishName.equals(dishs[i].name)) {
223                     return dishs[i];
224                 }
225             }
226             return null;
227         }
228         //根据菜名在菜谱中查找菜品信息,返回Dish对象。
229 
230         Dish addDish(String dishName,int unit_price,boolean special){
231             if(t>0){
232                 int k=t-1;
233                 for (;k>=0;k--){
234                     if (dishName.matches(dishs[k].name)){
235                         dishs[k].unit_price = unit_price;
236                         return null;
237                     }
238                 }
239             }
240             dishs[t] = new Dish(dishName,unit_price,special);
241             t++;
242             return dishs[t-1];
243         }//添加一道菜品信息
244 
245     }
246     class Record {
247 
248         int orderNum;//序号
249 
250         Dish d;//菜品\\
251         int portion;//份额(1/2/3代表小/中/大份)
252         int num;//数量
253         int week;//星期几
254         int shi;
255         int fen;
256         int miao;
257 
258         int life = 0;//初始为0,删除为1,重复删除为2,无视为3
259         public Record(){
260 
261         }
262         int getPrice(){
263             int s=1;
264             if(d.special==true) {//特价菜订单价格
265                 if (week <= 5 && week >= 1)
266                     s = (int)Math.round(d.getPrice(portion) * num * 0.7);
267                 else
268                     s = (int) Math.round(d.getPrice(portion) * num);
269             }
270             else{//普通菜订单价格
271                 if(week <= 5 && week >= 1) {
272                     if ((shi >= 17 && shi < 20) || (shi == 20 && fen <= 30))
273                         s = (int) Math.round(d.getPrice(portion) * num * 0.8);
274                     else
275                         s = (int) Math.round(d.getPrice(portion) * num * 0.6);
276                 }
277                 else
278                     s = (int) Math.round(d.getPrice(portion) * num);
279             }
280             return s;
281         }//计价,计算本条记录的价格
282         int ygetPrice(){
283             int s=1;
284             s = (int) Math.round(d.getPrice(portion) * num);
285             return s;
286         }
287 
288 }
289     class Order {
290 
291         Record[] records = new Record[100];//保存订单上每一道的记录
292         int i=0,s=0;//s为点菜数
293         int year;
294         int month;
295         int day;
296 
297 
298         public Order(){
299 
300         }
301 
302 
303         int getTotalPrice(){
304             int num = 0;
305             for(i=0;i<s;i++){
306                 if(records[i].life==0)
307                      num = num + records[i].getPrice();
308             }
309             return num;
310         }//计算订单的总价
311         int ygetTotalPrice(){
312             int num = 0;
313             for(i=0;i<s;i++){
314                 if(records[i].life==0)
315                     num = num + records[i].ygetPrice();
316             }
317             return num;
318         }//计算订单的原总价
319 
320         public Record addARecord(int orderNum,String dishName,int portion,int num,Menu menu,int week){
321 
322             for (i=0;i<s;i++){
323                 if(dishName==records[i].d.name&&portion==records[i].portion) {
324                     records[i].num = records[i].num + num;
325                     s++;
326                     return records[i];
327                 }
328             }
329             if(i==s) {
330 
331                 records[i] = new Record();
332                 if(menu.searthDish(dishName)!=null) {
333                     records[i].d = menu.searthDish(dishName);
334                     records[i].orderNum = orderNum;
335                     records[i].d.name = dishName;
336                     records[i].portion = portion;
337                     records[i].num = num;
338                     records[i].week = week;
339 
340                     s++;
341                 }
342                 else {
343                     records[i].d = new Dish();
344                     records[i].d.name=dishName;
345                     records[i].life=6;//订单的菜不存在
346                     s++;
347                 }
348                 return records[i];
349             }
350             return null;
351         }//添加一条菜品信息到订单中。
352 
353         public void delARecordByOrderNum(int orderNum){
354             for (i=0;i<s;i++){
355                 if(records[i].orderNum==orderNum){
356                     if(records[i].life==1)
357                         records[i].life = 2;
358                     else
359                         records[i].life = 1;
360                 }
361 
362             }
363 
364         }//根据序号删除一条记录
365 
366         public int findRecordByNum(int orderNum){
367             for (i=0;i<s;i++){
368                 if (records[i].orderNum==orderNum)
369                     return i;
370             }
371             return -1;
372         }//根据序号查找一条记录
373 
374     }
375     class Table {
376         Order order;
377         int num;
378         int year;
379         int month;
380         int day;
381         int shi;
382         int fen;
383         int miao;
384         int week;
385         public Table(){
386 
387         }
388         public boolean check(){
389             int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
390             if (month >= 1 && month <= 12) {
391                 //判断是否为闰年
392                 if ((year % 100 == 0 && year % 400 == 0) || year % 4 == 0) {
393                     //判断当前月份是否为2月,因为闰年的2月份为29天
394                     if (month == 2 && day <= 29) return true;
395                     else {
396                         if (day <= days[month - 1]) return true;
397                     }
398                 } else {
399                     if (day <= days[month - 1])
400                         return true;
401                 }
402             }
403             return false;
404         }
405         boolean checkorder(int x){//检查点菜序号
406             for(int j=0;j<=order.s-1;j++){
407                 if(x<=order.records[j].orderNum)
408                     return false;
409             }
410             return true;
411         }
412 
413     }

 

期中考试:

         期中考试的编程题主要考了封装、继承,最后一题时间不够还没有看,哭死好吧

        主要考了圆面积的计算和矩形面积的计算和封装,通过object图形类将圆形和矩形抽象出来,思路简单。

(3)采坑心得:

对菜单计价程序3的问题分析一下:

  1.日期判断的类有点小问题,不是很精确,有的时候会出错,最后一行本来应该输出table 2: 75,但是却显示超出营业时间,所以日期类其实是有点问题的。

    下面附一张运行结果的图:

(4)改进建议:

             对日期类的处理和异常值的判断太过于繁琐,很多if-else,调试起来经常容易忘自己是怎么想的,感觉还是要多注释一下。对日期类的的代码稍微修改了一下:

public double dateToday(String daytime,double zhekou){
        String[] split = daytime.split("/");
        int p= Integer.parseInt(split[0]);
        int p1= Integer.parseInt(split[1]);
        int p2= Integer.parseInt(split[2]);
        if(zhekou==1.0){
            if(p==9){
                if(p1>=30){
                    return zhekou*1.0;
                }
                return 0;
            }
            else if(p==21){
                if(p1<=29){
                    return 1.0*zhekou;
                }
                else if(p1==30){
                    if(p2==0){
                        return 1.0*zhekou;
                    }
                    return 0;
                }
                return 0;
            }
            else if(p2>=10 && p<=20){
                return 1.0*zhekou;
            }
            return 0;
        }
        else if(zhekou==0.8){
            if(p==20){
                if(p1<=29){
                    return 1.0*zhekou;
                }
                else if(p1==30){
                    if(p2==0){
                        return 1.0*zhekou;
                    }
                    return 0;
                }
                return 0;
            }
            else if(p>=17 && p<=19){
                return 1.0*zhekou;
            }
            if(p==10){
                if(p1>=30){
                    return zhekou*0.75;
                }
                return 0;
            }
            else if(p==14){
                if(p1<=29){
                    return 0.75*zhekou;
                }
                else if(p1==30){
                    if(p2==0){
                        return 0.75*zhekou;
                    }
                    return 0;
                }
                return 0;
            }
            else if(p2>=9 && p<=13){
                return 0.75*zhekou;
            }
            return 0;
        }
        return 0;
    }

  

(5)总结:对本阶段(6-11周)综合性总结,学到了什么,哪些地方需要进一步学习及研究,对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。

            这三次题目集算是真正了解类的定义与含义,不断刷新我对面向对象的理解,虽然代码多,但代码并不复杂,难点在于类的定义和类与类之间的关系,这个还是要多写。至于课堂,老师讲的我感觉懂了,但是自己写还是会有些不知如何下手,课下还是要多看书巩固实践一下,奥里给。