qq

发布时间 2023-04-29 05:55:29作者: 坤坤有手不行

1.前言

第四次题目集是三次题目集里题量最大的一次,二到四题主要是练习对数据的判断,处理,包括对数据的查找,删除排序,总体难度不是很大,但对算法有很高要求,容易运行超时。第一题和第五题主要练习我们对类与对象的使用,其中第一题更难,需要写多个类,题目较为复杂,难度大。第七题又是判断日期先后,计算隔天数,与前面的题目相比,我们不用自己写各种日期类和判断日期的方法,这次我们可以使用java里原本就有的有关日期的方法。难度不大。

第五次题目集题量看起来很大,但是前四题都比较简单,要求使用正则表达式。后两题是在第三次题目集的基础上,两题都给我们提供了类图,要求我们按类图要求写题,把以前的代码进行修改,难度还行。

第六次题目集就一题,是三次作业中最难的一题,要求特别多,测试点多,难度大。是在第四次第一题的基础上,增加更多需求,里面有复杂的判断条件。给出了多种异常情况,需要在程序中进行处理。

2.设计与分析

训练集004第一题:7-1 菜单计价程序-3

分数 30
作者 蔡轲
单位 南昌航空大学
设计点菜计价程序,根据输入的信息,计算并输出总价格。

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

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

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

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

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

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

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

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

删除记录格式:序号 delete

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

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

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

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

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

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

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

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

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

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

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

Dish {

String name;//菜品名称

int unit_price; //单价

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

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

Menu {

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

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

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

}

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

Record {

int orderNum;//序号\\

Dish d;//菜品\\

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

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

}

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

Order {

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

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

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

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

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

}

### 输入格式:

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

菜品记录格式:

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

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

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

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

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

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

### 输出格式:

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

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

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

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

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

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

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

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

菜品记录格式:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 12/2/3
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end
输出样例:
在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 38
输入样例1:
在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 17/0/0
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end
输出样例1:
在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 22
输入样例2:
在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 16/59/59
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end
输出样例2:
在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1 out of opening hours
输入样例3:
在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/5 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
7 delete
end
输出样例3:
在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
delete error;
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
table 1 out of opening hours
table 2: 63
输入样例4:
在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/3 19/5/12
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 4 麻婆豆腐 1 1
7 delete
end
输出样例4:
在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
4 table 2 pay for table 1 12
delete error;
table 1: 63
table 2: 75
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

试题分析:

这是比较复杂的一题,需要我们综合运用类的知识 ,包括类的定义,类的组合等。
本题要求设计一个点菜程序,需要实现以下功能:
输入菜单信息,包括菜名和基础价格;
输入订单信息,包括桌号标识、点菜记录、删除信息和代点菜信息;
计算每桌的总价,包括折扣计算;
输出每桌的订单记录处理信息和总价。
我们可以先定义一些类来实现这些功能:
Dish类:表示菜品,包含菜名和基础价格;
Menu类:表示菜单,包含所有菜品信息,可以通过菜名查找菜品信息;
Record类:表示点菜记录,包含序号、菜品信息、份额和份数,可以计算该记录的价格;
Order类:表示订单,包含多条点菜记录,可以添加、删除、查找记录,可以计算订单的总价;
Table类:表示桌子,包含桌号、订单信息和总价,可以添加、删除、查找订单,可以计算桌子的总价;

这题当时没有写,因为第四次作业题量较大,我第一次见过一道题的题目有这么长,看了一下题目,直接被吓的跳过了。然后做完后面的题目,没有时间来做这道题了。主要是对时间把控不到位,没有把时间全部用在写题目上,以后要注意。还有就是没有那种勇于探索的精神,遇到困难直接放弃了。

训练集004第三题:7-3 去掉重复的数据

分数 10
作者 翁恺
单位 浙江大学

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。
你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,去掉所有重复的数字。最后按照输入顺序输出没有重复数字的数据。所有重复的数字只保留第一次出现的那份。

输入格式:
你的程序首先会读到一个正整数 n,1≤n≤100000。
然后是 n 个整数,这些整数的范围是 [1, 100000]。

输出格式:
在一行中按照输入顺序输出去除重复之后的数据。每两个数据之间有一个空格,行首尾不得有多余空格。

输入样例:
5
1 2 2 1 4
输出样例:
1 2 4
代码长度限制
16 KB
时间限制
1500 ms
内存限制
150 MB

源代码展示:

查看代码

 

 import java.util.Scanner;
import java.util.LinkedHashSet;
public class Main {
    public static void main(String[] args) {
                Scanner input = new Scanner(System.in);
                int n = input.nextInt();
                LinkedHashSet<Integer> set = new LinkedHashSet<>();
                for(int i = 0;i<n;i++)
                set.add(input.nextInt());
                String number = set.toString();
                String numbers=number.substring(1,number.length()-1);
                String[] split = numbers.split(",");
                for(int i = 0;i<split.length;i++)
                       System.out.print(split[i]);
                }
        }

试题代码分析:

本题题目容易,但是很容易超时,为了让这题运行不会超时,我使用了LinkedHashSet,可以自动将输入的数据中重复的东西去除,且不会改变数据输入时的数据,但是用LinkedHashSet会使数据有,[]这些符号,我们用substring把一头一尾的[]去掉,然后用split分割字符串,遇到,就分割一次,刚好就可以正确输出。

 SourceMonitor生成的报表内容:

 

踩坑心得:

 

一开始使用数组来存入数据,然后一一遍历,删除重复数据,从逻辑上是对的但是运行超时了,然后我又想使用二分法提高运行效率,结果还是超时,最后用hashset存入数据,结果发现答案错误,查找资料得知,hashset在存入数据时虽然不会输入重复数据,但是可能改变顺序,最后是用了LinkHashset才做对的。

改进建议:

用linkhashset可以做对这题,但并不是常归方法,如果可以用数组或arrylist存入数据,用简单的算法做出这题会更好。

 

训练集004第四题:7-4 单词统计与排序

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

输入格式:
一段英文文本。

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

输入样例:
Hello, I am a student from China.
输出样例:
student
China
Hello
from
am
a
I
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

源代码展示:

查看代码

 

 import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String[] word = new String[100];
        int[] num = new int[100];
        String t = null;
        int a = 0,m=19;
        String english = input.nextLine();
        String[] split = english.split(" ");
        for(int i = 0;i < split.length;i++) {
               for(int j=0;j<split[i].length();j++) {
                    if(split[i].charAt(j)==','||split[i].charAt(j)=='.') {
                               split[i] = split[i].substring(0,split[i].length()-1);
                       }
               }
        }
        for(int i = 0;i < split.length;i++){
            split[i].toLowerCase();
        }
        for(int i = 0;i < split.length;i++) {
               num[i] = split[i].length();
        }
        
        for(int i = 0;i<split.length;i++) {
               for(int j = 0;j < split.length - i - 1;j ++) {
                       if(num[j] < num[j+1]) {
                               t = split[j];
                               split[j] = split[j+1];
                               split[j+1] = t;
                               a = num[j];
                               num[j] = num[j+1];
                               num[j+1] = a;
                       }}}
                       //if(num[j]==num[j+1]) {
        for(int i = 0;i<split.length;i++) {
               for(int j = 0;j < split.length - i - 1;j ++) {
                               for(int k = 0;k<num[j];k++) {
                                 if(num[j]==num[j+1]&&split[j].toLowerCase().charAt(k) > split[j+1].toLowerCase().charAt(k)) {
                                              t = split[j];
                                       split[j] = split[j+1];
                                       split[j+1] = t;
                                       a = num[j];
                                       num[j] = num[j+1];
                                       num[j+1] = a;
                                       break;
                                      }
                                       if(num[j]!=num[j+1])
                                              break;
                        if(split[j].equals(split[j+1]))
                                              {
                                      break;}
                                if(split[j].toLowerCase().charAt(k)==split[j+1].toLowerCase().charAt(k)) {
                                              continue;
                                      }
                                       if(split[j].toLowerCase().charAt(k) < split[j+1].toLowerCase().charAt(k)) {
                                              break;
                                      }
                               }
                       
               }
        }
      
        System.out.println(split[0]);
        for(int i=1;i<split.length;i++) {
               if(split[i].equals(split[i-1]))
                       continue;
        System.out.println(split[i]);
        }
        
        
    }}

 

试题代码分析:

输入一个长字符串,用split分割这个字符串,当遇到空格、逗号或句号时就分割一次。接下来判断子字符串长度,按长度递减排列,如果遇到相同长度的字符,就比较首字母的先后顺序,如果还是相等就往后比较,如果比到最后一位还是相等,则说明两个字符相同,结束本次循环,不输出重复字符串。

SourceMonitor生成的报表内容:

 

踩坑心得:

 

在写代码的时候没有考虑到同一个单词可能出现在不同位置多次,一开始使用的类似冒泡法来排序,当在不同位置出现多个相同的单词且字符长度相同时,排序可能不正确。导致较长文本输出错误。

改进建议:

for循环写的不够简化,可以优化for循环。

 

训练集004第五题:7-5 日期问题面向对象设计(聚合一)

分数 50
作者 段喜龙
单位 南昌航空大学
参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

应用程序共测试三个功能:

求下n天
求前n天
求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):

1 year month day n //测试输入日期的下n天
2 year month day n //测试输入日期的前n天
3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
当输入有误时,输出格式如下:
Wrong Format
当第一个数字为1且输入均有效,输出格式如下:
year-month-day
当第一个数字为2且输入均有效,输出格式如下:
year-month-day
当第一个数字为3且输入均有效,输出格式如下:
天数值
输入样例1:
在这里给出一组输入。例如:

3 2014 2 14 2020 6 14
输出样例1:
在这里给出相应的输出。例如:

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

2 1935 2 17 125340
输出样例2:
在这里给出相应的输出。例如:

1591-12-17
输入样例3:
在这里给出一组输入。例如:

1 1999 3 28 6543
输出样例3:
在这里给出相应的输出。例如:

2017-2-24
输入样例4:
在这里给出一组输入。例如:

0 2000 5 12 30
输出样例4:
在这里给出相应的输出。例如:

Wrong Format
代码长度限制
16 KB
时间限制
10000 ms
内存限制
64 MB

源代码展示:

 

查看代码

 

 
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;
        int choice = input.nextInt();
        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
 
            DateUtil date = new DateUtil(year, month, day);
 
            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
            m = input.nextInt();
 
            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
          //  System.out.print(date.day.getMonth().getYear().getValue() + "-" + date.day.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
 
            DateUtil date = new DateUtil(year, month, day);
 
            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
            n = input.nextInt();
 
            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
            //System.out.print(
             //       date.day.getMonth().getYear().getValue() + "-" + date.day.getMonth().getValue() + "-" + date.day.getValue() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) {    //test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
 
            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());
 
            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
 
            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println( fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
        else{
            System.out.println("Wrong Format");
            System.exit(0);
        }        
    }
}
class DateUtil{
    //private int day;
    Day day;
    public DateUtil(){
        
    }
    public DateUtil(int d, int m, int y){
        this.day = new Day(d,m,y);
      //  this.d = d;
     //   this.m = m;
      //  this.y = y;
    }
    public Day getDay(){
        return day;
    }
    public void setDay(Day d){
        this.day = d;
    }
    public boolean checkInputValidity() {
        if(day.validate()&&day.getMonth().validate()&&day.getMonth().getYear().validate())
            return true;
        else 
            return false;
    }
    public boolean compareDates(DateUtil date) {
    if(day.getMonth().getYear().getValue() > date.day.getMonth().getYear().getValue()) {
              return false;
    }
             else if(day.getMonth().getYear().getValue() < date.day.getMonth().getYear().getValue()){
             return true;
            }
        else {
              if(day.getMonth().getValue() > date.day.getMonth().getValue()) {
              return false;
              }
              else if(day.getMonth().getValue() < date.day.getMonth().getValue()) {
              return true;
         }
              else {
              if(day.getValue()>date.day.getValue()) {
              return false;
               }
              else {
                  return true;
                  }
             }
         }
    }
        public boolean equalTwoDates(DateUtil date) {
          if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&date.day.getValue()==day.getValue()&&date.day.getMonth().getValue()==day.getMonth().getValue()) {
          return true;
    }
          else {
          return false;
    }
    }
        public String showDate() {
        return (day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue());
    }
         
               public DateUtil getNextNDays(int m){
                int d;
      /* while(true){
           if(day.getMonth().getYear().isLeapYear()){
               if(m>366){
                   m=m-366;
                   day.getMonth().getYear().yearIncrement();
               }
               else
                   break;
           }
           else{
               if(m>365){
                   m=m-365;
                   day.getMonth().getYear().yearIncrement();
               }
               else
                   break;
           }
       }*/
         
         while(true){
             int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(day.getMonth().getYear().isLeapYear())
            a[2] = 29;
             if(m+day.getValue()<=a[day.getMonth().getValue()]){
               // for(int i = 0;i < m;i++) 
               // day.dayIncrement();
                 d = day.getValue() + m;
              break;
              }
             if(m+day.getValue()>a[day.getMonth().getValue()]){
                 m=m-a[day.getMonth().getValue()];
                 day.getMonth().monthIncrement();
             }
             if(day.getMonth().getValue()==13){
                day.getMonth().resetMin();
                 day.getMonth().getYear().yearIncrement();
             }
             
         }
        
        
                
                
        
         DateUtil nextdate = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), d);
        return nextdate;
               }
        public DateUtil getPreviousNDays(int m){
            //   int day1 = day;
          //   int month1 = month;
           //  int year1 = year;
               
               int i;
               
               
               int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
                            while(true){
                  if(day.getMonth().getYear().isLeapYear()){
                      if(m>366){
                          m=m-366;
                          day.getMonth().getYear().yearReduction();
                      }
                      else
                          break;
                  }
                  else{
                      if(m>365){
                          m=m-365;
                          day.getMonth().getYear().yearReduction();
                      }
                      else
                          break;
                  }
              }
               for(i=0;i<m;i++){
               if(day.getMonth().getYear().isLeapYear())
                   a[2]=29;
               
               if(day.getValue()==1){
               day.getMonth().monthReduction();
               if(day.getMonth().getValue()==0){
                   day.getMonth().resetMax();
                   day.getMonth().getYear().yearReduction();
               }
                day.resetMax();}
               else
                   day.dayReduction();
               }
               
              
                   DateUtil beforedate = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue());
               return beforedate;
           }
         public int getDaysofDates(DateUtil date) {
                   
                       boolean b = equalTwoDates(date);
                       boolean x = compareDates(date);
               int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
                       //     int[] m = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
               int year1 = day.getMonth().getYear().getValue();
               int month1 =day.getMonth().getValue();
               int day1 = day.getValue();
               int year2 = date.day.getMonth().getYear().getValue();
               int month2 =date.day.getMonth().getValue();
               int day2 = date.day.getValue();
                       int k = 0;
                       int i;
                       if(b) {
                              k = 0;
                       }
                       else{
                           if(x){
                               if(year1<=year2){
                                   for(i=year1;i<year2;i++){
                                       if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
                                           k=k+366;
                                       else
                                           k=k+365;
                                   }
                               }
                        //       if(year==toDate.year){
                                   if(month1<month2){
                                       for(i=month1;i<month2;i++){
                                           
                       if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
                           a[2]=29;
                                           k=k+a[i];
                                       }
                                   }
                                   if(month1>=month2){
                                       for(i=month2;i<month1;i++){
                                              if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
                                   a[2]=29;
                                           k=k-a[i];
                                       }
                                   }
                               
                                k=k+day2-day1;
                           }
                           else{
                               //
                                               if(year1>=year2){
                                   for(i=year2;i<year1;i++){
                                      if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
                                           k=k+366;
                                       else
                                           k=k+365;
                                   }
                               }
                        //       if(year==toDate.year){
                                   if(month2<month1){
                                       for(i=month2;i<month1;i++){
                                           
                                              if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
                           a[2]=29;
                                           k=k+a[i];
                                       }
                                   }
                                   if(month2>=month1){
                                       for(i=month1;i<month2;i++){
                                              if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
                                   a[2]=29;
                                           k=k-a[i];
                                       }
                                   }
                               
                                k=k-day2+day1;
                           }
                       }
                       return k;
         }
}
class Day{
    private int value;
    Month month;
    int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31};
    public Day(){
        
    }
    public Day(int yearValue, int monthValue, int dayValue){
        this.month = new Month(yearValue,monthValue);
        this.value = dayValue;
    }
    public int getValue(){
        return value;
    }
    public void setValue(int value){
        this.value = value;
    }
    public Month getMonth(){
        return month;
    }
    public void setMonth(Month value){
        this.month = value;
    }
    public void resetMin(){
        value = 1;
    }
    public void resetMax(){
        //if(month.getYear().isLeapYear())
            //  mon_maxnum[1] = 29;
        value = mon_maxnum[month.getValue() - 1];
    }
    public boolean validate(){
        if(month.getValue()>=13||month.getValue()<=0) {
               return false;
        }
        if(month.getYear().isLeapYear())
            mon_maxnum[1] = 29;
        if(value >= 1&&value <= mon_maxnum[month.getValue() - 1])
            return true;
        else
            return false;
    }
    public void dayIncrement (){
        value = value + 1;
    }
    public void dayReduction (){
        value = value - 1;
    }
}
class Month{
    private int value;
    Year year;
    public Month(){
        
    }
    public Month(int yearValue, int monthValue){
        this.year = new Year(yearValue);
        this.value = monthValue;
    }
    public int getValue(){
        return value;
    }
    public void setValue(int value){
        this.value = value;
    }
    public Year getYear(){
        return year;
    }
    public void setYear(Year year){
        this.year = year;
    }
    public void resetMin(){
        value = 1;
    }
    public void resetMax(){
        value = 12;
    }
    public boolean validate(){
        if(value >= 1&&value <= 12)
            return true;
        else 
            return false;
    }
    public void monthIncrement (){
        value = value + 1;
    }
    public void monthReduction (){
        value = value - 1;
    }
}
class Year{
    private int value;
    public Year(){
        
    }
    public Year(int value){
        this.value = value;
    }
    public int getValue(){
        return value;
    }
    public void setValue(int value){
        this.value = value;
    }
    public boolean isLeapYear(){
        if((value%4 == 0&&value%100 != 0)||(value%400 == 0))
                       return true;
                       else 
                return false;
    }
    public boolean validate(){
        if(value>=1900&&value<=2050)
            return true;
        else
            return false;
    }
    public void yearIncrement (){
        value = value + 1;
    }
    public void yearReduction (){
        value = value - 1;
    }
}

试题代码分析:

用了聚合,month里有year,day里有month,在使用年月日的类的时候,层层套用,年月日的类中有不同的方法。

SourceMonitor生成的报表内容:

 

 

踩坑心得:

判断年月日的日期合法性时,没有正确调用不同类的方法,导致日期合法性报错。一开始做题时,没有把握好不同类之间的关系,在调用时会出错。

改进建议:

有些方法虽然在类图中有,但是感觉作用不大,可以删除。

训练集005第六题:7-6 日期问题面向对象设计(聚合二)

分数 34
作者 段喜龙
单位 南昌航空大学
参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

应用程序共测试三个功能:

求下n天
求前n天
求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):

1 year month day n //测试输入日期的下n天
2 year month day n //测试输入日期的前n天
3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
当输入有误时,输出格式如下:
Wrong Format
当第一个数字为1且输入均有效,输出格式如下:
year1-month1-day1 next n days is:year2-month2-day2
当第一个数字为2且输入均有效,输出格式如下:
year1-month1-day1 previous n days is:year2-month2-day2
当第一个数字为3且输入均有效,输出格式如下:
The days between year1-month1-day1 and year2-month2-day2 are:值
输入样例1:
在这里给出一组输入。例如:

3 2014 2 14 2020 6 14
输出样例1:
在这里给出相应的输出。例如:

The days between 2014-2-14 and 2020-6-14 are:2312
输入样例2:
在这里给出一组输入。例如:

2 1834 2 17 7821
输出样例2:
在这里给出相应的输出。例如:

1834-2-17 previous 7821 days is:1812-9-19
输入样例3:
在这里给出一组输入。例如:

1 1999 3 28 6543
输出样例3:
在这里给出相应的输出。例如:

1999-3-28 next 6543 days is:2017-2-24
输入样例4:
在这里给出一组输入。例如:

0 2000 5 12 30
输出样例4:
在这里给出相应的输出。例如:

Wrong Format
代码长度限制
16 KB
时间限制
10000 ms
内存限制

源代码展示:

 

查看代码

 

 
import java.util.Scanner;
 
 
 
 
public class Main {
 
        public static void main(String[] args) {
               // TODO Auto-generated method stub
               Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;
        int choice = input.nextInt();
        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
 
            DateUtil date = new DateUtil(year, month, day);
 
            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
            m = input.nextInt();
 
            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
            System.out.print(date.year.getValue() + "-" + date.month.getValue() + "-" + date.day.getValue() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
 
            DateUtil date = new DateUtil(year, month, day);
 
            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
            n = input.nextInt();
 
            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
 
            System.out.print(
                    date.year.getValue() + "-" + date.month.getValue() + "-" + date.day.getValue() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) {    //test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
 
            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());
 
            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
 
            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
               System.out.println("The days between " + fromDate.showDate() + 
                        " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
        else{
            System.out.println("Wrong Format");
            System.exit(0);
        }        
    }
        }
 
 
class Day{
        private int value;
        
        public Day(int value) {
               super();
               this.value = value;
        }
 
        public Day() {
               super();
               // TODO Auto-generated constructor stub
        }
 
        public int getValue() {
               return value;
        }
 
        public void setValue(int value) {
               this.value = value;
        }
        public void dayIncrement() {
               value = value + 1;
        }
        public void dayReduction() {
               value = value - 1;
        }
}
class Year{
        private int value;
 
        public Year(int value) {
               super();
               this.value = value;
        }
 
        public Year() {
               super();
               // TODO Auto-generated constructor stub
        }
 
        public int getValue() {
               return value;
        }
 
        public void setValue(int value) {
               this.value = value;
        }
        public boolean isLeapYear() {
               if((value%4 == 0&&value%100 != 0)||(value%400 == 0))
                       return true;
                       else 
                return false;
        }
        public boolean validate() {
               if(value >= 1820&&value <= 2020)
                       return true;
               else 
                       return false;
        }
        public void yearIncrement() {
               value = value + 1;
        }
        public void yearReduction() {
               value = value - 1;
        }
}
class Month{
        private int value;
 
        public int getValue() {
               return value;
        }
 
        public void setValue(int value) {
               this.value = value;
        }
 
        public Month() {
               super();
               // TODO Auto-generated constructor stub
        }
 
        public Month(int value) {
               super();
               this.value = value;
        }
        public void resetMin() {
               value = 1;
        }
        public void resetMax() {
               value = 12;
        }
        public boolean validate() {
               if(value >= 1&&value <= 12)
                       return true;
               else 
                       return false;
        }
        public void monthIncrement() {
               value = value + 1;
        }
        public void monthReduction() {
               value = value - 1;
        }
}
class DateUtil{
        Year year;
        Month month;
        Day day;
        int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31};
        public DateUtil(int y, int m, int d) {
               super();
               this.year = new Year(y);
               this.month = new Month(m);
               this.day = new Day(d);
        }
        public DateUtil() {
               super();
               // TODO Auto-generated constructor stub
        }
        public Year getYear() {
               return year;
        }
        public void setYear(Year year) {
               this.year = year;
        }
        public Month getMonth() {
               return month;
        }
        public void setMonth(Month month) {
               this.month = month;
        }
        public Day getDay() {
               return day;
        }
        public void setDay(Day day) {
               this.day = day;
        }
        public void setDayMin() {
               day.setValue(1);
        }
        public void setDayMax() {
               if(year.isLeapYear())
                       mon_maxnum[1] = 29;
               day.setValue(mon_maxnum[day.getValue() - 1]);
        }
        public boolean checkInputValidity() {
          if(month.validate()&&year.validate()&&day.getValue() >= 1&&day.getValue() <=mon_maxnum[month.getValue() - 1] )
            return true;
        else 
            return false;
        }
        public DateUtil getNextNDays(int m) {
               int d;
                 
                 while(true){
                     int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
                if(year.isLeapYear())
                    a[2] = 29;
                     if(m+day.getValue()<=a[month.getValue()]){
                       // for(int i = 0;i < m;i++) 
                       // day.dayIncrement();
                         d = day.getValue() + m;
                      break;
                      }
                     if(m+day.getValue()>a[month.getValue()]){
                         m=m-a[month.getValue()];
                         month.monthIncrement();
                     }
                     if(month.getValue()==13){
                        month.resetMin();
                         year.yearIncrement();
                     }
                     
                 }
                
                
                        
                        
                
                 DateUtil nextdate = new DateUtil(year.getValue(), month.getValue(), d);
                return nextdate;
        }
        public DateUtil getPreviousNDays(int m){
        //   int day1 = day;
      //       int month1 = month;
       //      int year1 = year;
           
           int i;
           
           
           int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
                        while(true){
              if(year.isLeapYear()){
                  if(m>366){
                      m=m-366;
                      year.yearReduction();
                  }
                  else
                      break;
              }
              else{
                  if(m>365){
                      m=m-365;
                      year.yearReduction();
                  }
                  else
                      break;
              }
          }
           for(i=0;i<m;i++){
           if(year.isLeapYear())
               a[2]=29;
           
           if(day.getValue()==1){
           month.monthReduction();
           if(month.getValue()==0){
               month.resetMax();
               year.yearReduction();
           }
            setDayMax();}
           else
               day.dayReduction();
           }
           
          
               DateUtil beforedate = new DateUtil(year.getValue(), month.getValue(), day.getValue());
        return beforedate;
       }
        public boolean compareDates(DateUtil date) {
            if(year.getValue() > date.year.getValue()) {
                      return false;
            }
                     else if(year.getValue() < date.year.getValue()){
                     return true;
                    }
                else {
                      if(month.getValue() > date.month.getValue()) {
                      return false;
                      }
                      else if(month.getValue() < date.month.getValue()) {
                      return true;
                 }
                      else {
                      if(day.getValue()>date.day.getValue()) {
                      return false;
                       }
                      else {
                          return true;
                          }
                     }
                 }
            }
         public boolean equalTwoDates(DateUtil date) {
         if(date.year.getValue() == year.getValue()&&date.day.getValue()==day.getValue()&&date.month.getValue()==month.getValue()) {
         return true;
   }
         else {
         return false;
   }
   }
         public int getDaysofDates(DateUtil date) {
            
                boolean b = equalTwoDates(date);
                boolean x = compareDates(date);
        int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
                //     int[] m = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        int year1 = year.getValue();
        int month1 =month.getValue();
        int day1 = day.getValue();
        int year2 = date.year.getValue();
        int month2 =date.month.getValue();
        int day2 = date.day.getValue();
                int k = 0;
                int i;
                if(b) {
                       k = 0;
                }
                else{
                    if(x){
                        if(year1<=year2){
                            for(i=year1;i<year2;i++){
                                if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
                                    k=k+366;
                                else
                                    k=k+365;
                            }
                        }
                 //       if(year==toDate.year){
                            if(month1<month2){
                                for(i=month1;i<month2;i++){
                                    
                if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
                    a[2]=29;
                                    k=k+a[i];
                                }
                            }
                            if(month1>=month2){
                                for(i=month2;i<month1;i++){
                                       if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
                            a[2]=29;
                                    k=k-a[i];
                                }
                            }
                        
                         k=k+day2-day1;
                    }
                    else{
                        //
                                        if(year1>=year2){
                            for(i=year2;i<year1;i++){
                               if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
                                    k=k+366;
                                else
                                    k=k+365;
                            }
                        }
                 //       if(year==toDate.year){
                            if(month2<month1){
                                for(i=month2;i<month1;i++){
                                    
                                       if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
                    a[2]=29;
                                    k=k+a[i];
                                }
                            }
                            if(month2>=month1){
                                for(i=month1;i<month2;i++){
                                       if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
                            a[2]=29;
                                    k=k-a[i];
                                }
                            }
                        
                         k=k-day2+day1;
                    }
                }
                return k;
}
         public String showDate() {
                return (year.getValue()+"-"+month.getValue()+"-"+day.getValue());
            }
         
}

试题代码分析:

年月日的类里只有基本属性,各种判断,计算的方法都放在dateutil类里面,判断闰年的方法没有变,重点是由往前一天变到n天,就要考虑有跨年,跨月的情况,我利用上一题的原理,相当于往前加n个一天,用一个for循环每次往前加一天,跨越月份或年份就往前加一,天数从1开始重新记算,用if来实现。往前多少天也是同一原理,先算往前一天,然后用循环。题目还要求可以求两日期的天数差,首先要判断前后输入的日期谁大谁小,按题目要求如果前面的日期大,就返回真,后面大返回假。计算日期差值,以前面的日期大为例:先判断两日期年份是否相同,如果相同就判断月份,不相同就两个年份相减每差一年就加上对就年的天数,然后判断月份,如果是前面的日期月份大,就加上这两月份相差的天数,要是整的月份,反之减去相差天数,最后判断天数,与月份逻辑相同,最后将年月日的得的结果放一起就是差的天数。

SourceMonitor生成的报表内容:

 

踩坑心得:

 

计算前多少天后多少天时,算法不是很好,导致运行可能超时。再计算最大值时出现错误。

改进建议:

改进算法,使得计算结果不会出错。

训练集006第一题:7-1 菜单计价程序-4

 

分数 100
作者 蔡轲
单位 南昌航空大学
本体大部分内容与菜单计价程序-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+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价

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

麻婆豆腐 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
其他用例请参考公开的测试用例

代码长度限制
50 KB
时间限制
1000 ms
内存限制
64 MB

 

题目分析:

题目与第四次实验第一题相似,但是上次的实验第一题没有做出来,结果这次也没做出来。

 

 

 总结:

这三次比上三次要难上许多,让我们更加熟练的使用类,对类的理解更深入,也发现许多存在的问题,在遇到难题的时候没有坚忍的心态,导致没有好好努力去做菜单的题目,为此要吸取教训,下次一定挑战到底,无论任何题目都不放弃。给老师的建议:希望以后出比较难的题目时能多给点思路上的提示。