JavaBlog作业2

JAVA题目集4~6总结

一、前言:

第四次题目集整体难度不高,属于过渡性质的训练,有为后面铺垫的菜单计价程序-3,跟前面题目集一样的查找重复数据,7-7还要我们去稍微了解很多之前没接触的类和方法。
第五次题目集主要知识点是正则表达式和类图的了解,前几题都是很简单的正则表达式的应用题目,最后两个较长的日期问题前面也都做过,只不过这回要根据类图来编写,很多前面的代码都可以直接照搬,难度并不高。
第六次题目集虽然只有一题,但却是遇到的最难的题目,是前面菜单计价程序-3的升级版菜单计价程序-4,前面的菜单计价程序-3摸了导致这题花了大量的时间,最后也没有完全做完。要运用前面学到的很多知识点,最重要的是要在编写前理解题目并构建好框架,不然就会面临多次的大规模重写。难度很高。


二、设计与分析:

1.题目集4(7-1)菜单计价程序-3和题目集6(7-1)菜单计价程序-4

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

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

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

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

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

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

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

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

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

删除记录格式:序号 delete

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

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

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

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

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

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

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

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

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

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

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

Dish {

String name;//菜品名称

int unit_price; //单价

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

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

Menu {

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

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

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

}

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

Record {

int orderNum;//序号\

Dish d;//菜品\

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

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

}

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

Order {

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

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

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

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

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

}

输入格式:

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

菜品记录格式:

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

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

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

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

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

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

输出格式:

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

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

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

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

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

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

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

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

菜品记录格式:

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

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

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

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

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

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

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

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

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

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

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

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

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

7-1 菜单计价程序-4

本体大部分内容与菜单计价程序-3相同,增加的部分用加粗文字进行了标注。

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

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

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

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

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

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

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

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

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

删除记录格式:序号 delete

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

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

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

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

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

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

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

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

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

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

参考以下类的模板进行设计(本内容与计价程序之前相同,其他类根据需要自行定义):

菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

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

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

Menu {

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

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

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

}

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

Record {

int orderNum;//序号

Dish d;//菜品\

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

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

}

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

Order {

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

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

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

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

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

}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

例如:麻婆豆腐 9 T

菜价的计算方法:

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

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

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

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

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

菜品记录格式:

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

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

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

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

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

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

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

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

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

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

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

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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
    public static void main(String[] args) throws ParseException {
        Scanner input = new Scanner(System.in);
        int i, t = 0, year, month, day, shi, fen, miao, f = 0, y = -1;
        String a = null;
        Menu menu = new Menu();
        Table[] tables = new Table[10];
        for (i = 0; ; i++) {
            if(f==1)
                break;
            if (y == -1)
                a = input.nextLine();
            if (a.equals("end"))
                break;
            String[] s = a.split(" ");
            int x = s.length;
            if (x <= 3 && t == 0) {//菜品
                int l = 0;
                int n = 0;
                if (!s[1].matches("[1-9]||[1-9][0-9]||[1-2][0-9][0-9]")) {
                    System.out.println("wrong format");
                    menu.dishs[menu.t] = new Dish();
                } else {
                    n = Integer.parseInt(s[1]);
                    boolean special = false;
                    if (x == 3) {
                        if(s[2].matches("T"))
                        special = true;
                       else{
                           System.out.println("wrong format");
                    System.exit(0);
                       }
                    }
                    menu.addDish(s[0], n, special);
                    if (n <= 0 || n >= 300) {//菜价超出范围
                        System.out.println(s[0] + " price out of range " + n);
                    }
                }
            } else {

                t = 1;
                if(x>4){
                    System.out.println("wrong format");
                    System.exit(0);
                }
                while (true) {
                    if(f==1)
                        break;
                    y++;
                    if (x == 4 && !(s[0].matches("table")) && y == 0) {//第一个
                        System.out.println("wrong format");
                        System.exit(0);
                    }
                    while ((x == 4 && s[0].matches("table")) || y > 0) {
                        if(f==1)
                            break;
                        if (s.length == 4) {////后面的桌子直接进入点菜,后面所有的信息并入上一桌一起计算
                            tables[y] = new Table();
                            tables[y].order = new Order();
                            String[] s1 = s[2].split("/");//年月日的分割
                            String[] s2 = s[3].split("/");//时分秒的分割
                            SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd");
                            SimpleDateFormat d2 = new SimpleDateFormat("u");
                            Date date = d.parse(s1[0] + "-" + s1[1] + "-" + s1[2]);//日期格式化
                            int week = Integer.parseInt(d2.format(date));//提取星期几
                            tables[y].week = week;
                            if (!s[1].matches("\\d*")) {//检查"table"部分
                                System.out.println("wrong format");
                                if (y == 0)//第一个桌子桌号错误直接退出
                                    System.exit(0);
                                else//后面所有的信息并入上一桌一起计算
                                    y--;
                            } else {
                                tables[y].num = Integer.parseInt(s[1]);
                                tables[y].year = Integer.parseInt(s1[0]);
                                tables[y].month = Integer.parseInt(s1[1]);
                                tables[y].day = Integer.parseInt(s1[2]);
                                tables[y].shi = Integer.parseInt(s2[0]);
                                tables[y].fen = Integer.parseInt(s2[1]);
                                tables[y].miao = Integer.parseInt(s2[2]);
                                if(s[1].matches("[0].+")){
                                    System.out.println("wrong format");
                                    System.exit(0);
                                }

                                if (!(tables[y].num <= 55 && tables[y].num >= 1)) {
                                    System.out.println("table num out of range");
                                    System.exit(0);
                                }
                                else if(!tables[y].check()){
                                    System.out.println(tables[y].num+" date error");
                                    System.exit(0);
                                }
                                else if(tables[y].year>2023||tables[y].year<2022){
                                    System.out.println("not a valid time period");
                                    System.exit(0);
                                }
                                else
                                    System.out.println("table " + Integer.parseInt(s[1]) + ": ");
                            }
                        } else {
                            System.out.println("wrong format");
                            f = 0;
                            y--;//数据并入上一卓
                        }
                        for (; ; i++) {//点菜
                            if (f == 1 || f == 2)
                                break;
                            String aa = input.nextLine();
                            String[] ss = aa.split(" ");
                            //System.out.println(y + "---------" + aa);
                            if (ss.length == 4 && ss[0].charAt(0) == 't') {//新桌子
                                s = ss;
                                y++;
                                break;
                            }
                            if (ss.length == 4) {//点菜
                                //System.out.println(y+"%"+ss[0]);
                                //tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
                                if (!tables[y].checkorder(Integer.parseInt(ss[0])))//检查订单序号顺序
                                    System.out.println("record serial number sequence error");
                                else if (menu.searthDish(ss[1])==null)//订单的菜不存在
                                    System.out.println(ss[1] + " does not exist");
                                else if (Integer.parseInt(ss[2]) > 3) {//份额超过3
                                    System.out.println(ss[0] + " " + "portion out of range" + " " + ss[2]);
                                } else if (Integer.parseInt(ss[3]) > 15) {//订单大于15
                                    System.out.println(ss[0] + " " + "num out of range" + " " + ss[3]);
                                } else {
                                    tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
                                    System.out.println(ss[0] + " " + ss[1] + " " + tables[y].order.records[tables[y].order.s - 1].ygetPrice());
                                    tables[y].order.records[tables[y].order.s - 1].shi=tables[y].shi;
                                    tables[y].order.records[tables[y].order.s - 1].fen=tables[y].fen;
                                    
                                }
                            }
                            if (ss.length == 2 && ss[1].matches("delete")) {//删除
                                if(tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))==-1) {
                                    System.out.println("delete error");
                                }
                                else {

                                    tables[y].order.delARecordByOrderNum(Integer.parseInt(ss[0]));
                                    if (tables[y].order.records[tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))].life == 2) //重复删除的情况
                                        System.out.println("deduplication " + ss[0]);
                                }
                            }
                            if ((ss.length == 2 || ss.length == 3) && !ss[1].matches("delete")) {
                                System.out.println("invalid dish");
                            }
                            if (ss.length > 4) {
                                a = aa;
                                s = a.split(" ");

                                f = 2;

                            }
                           // System.out.println("////");
                        /*if(ss.length==5){//代点菜
                            for(int t=0;t<=y;t++){
                                if(ss[0].equals(tables[i].num))
                            }
                        }*/
                            if (aa.equals("end")) {
                                f = 1;
                                break;
                            }

                        }
                        if (f == 1 || f == 2)
                            break;
                    }
                    if (f == 1)
                        break;
                }
            }
            }
            for (i = 0; i <= y; i++) {
                System.out.println("table " + tables[i].num + ": " + tables[i].order.ygetTotalPrice() + " " + tables[i].order.getTotalPrice());
            }
    }
}

    class Dish {

        String name;//菜品名称

        int unit_price; //单价
        int life=0;//
        boolean special = false;
        public Dish(){

        }
        public Dish(String name,int unit_price,boolean special){
            this.name = name;
            this.unit_price = unit_price;
            this.special = special;
        }

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

        Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息
        int t=0;
        public Menu(){

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

        Dish addDish(String dishName,int unit_price,boolean special){
            if(t>0){
                int k=t-1;
                for (;k>=0;k--){
                    if (dishName.matches(dishs[k].name)){
                        dishs[k].unit_price = unit_price;
                        return null;
                    }
                }
            }
            dishs[t] = new Dish(dishName,unit_price,special);
            t++;
            return dishs[t-1];
        }//添加一道菜品信息

    }
    class Record {

        int orderNum;//序号

        Dish d;//菜品\\
        int portion;//份额(1/2/3代表小/中/大份)
        int num;//数量
        int week;//星期几
        int shi;
        int fen;
        int miao;

        int life = 0;//初始为0,删除为1,重复删除为2,无视为3
        public Record(){

        }
        int getPrice(){
            int s=1;
            if(d.special==true) {//特价菜订单价格
                if (week <= 5 && week >= 1)
                    s = (int)Math.round(d.getPrice(portion) * num * 0.7);
                else
                    s = (int) Math.round(d.getPrice(portion) * num);
            }
            else{//普通菜订单价格
                if(week <= 5 && week >= 1) {
                    if ((shi >= 17 && shi < 20) || (shi == 20 && fen <= 30))
                        s = (int) Math.round(d.getPrice(portion) * num * 0.8);
                    else
                        s = (int) Math.round(d.getPrice(portion) * num * 0.6);
                }
                else
                    s = (int) Math.round(d.getPrice(portion) * num);
            }
            return s;
        }//计价,计算本条记录的价格
        int ygetPrice(){
            int s=1;
            s = (int) Math.round(d.getPrice(portion) * num);
            return s;
        }

}
    class Order {

        Record[] records = new Record[100];//保存订单上每一道的记录
        int i=0,s=0;//s为点菜数
        int year;
        int month;
        int day;


        public Order(){

        }


        int getTotalPrice(){
            int num = 0;
            for(i=0;i<s;i++){
                if(records[i].life==0)
                     num = num + records[i].getPrice();
            }
            return num;
        }//计算订单的总价
        int ygetTotalPrice(){
            int num = 0;
            for(i=0;i<s;i++){
                if(records[i].life==0)
                    num = num + records[i].ygetPrice();
            }
            return num;
        }//计算订单的原总价

        public Record addARecord(int orderNum,String dishName,int portion,int num,Menu menu,int week){

            for (i=0;i<s;i++){
                if(dishName==records[i].d.name&&portion==records[i].portion) {
                    records[i].num = records[i].num + num;
                    s++;
                    return records[i];
                }
            }
            if(i==s) {

                records[i] = new Record();
                if(menu.searthDish(dishName)!=null) {
                    records[i].d = menu.searthDish(dishName);
                    records[i].orderNum = orderNum;
                    records[i].d.name = dishName;
                    records[i].portion = portion;
                    records[i].num = num;
                    records[i].week = week;

                    s++;
                }
                else {
                    records[i].d = new Dish();
                    records[i].d.name=dishName;
                    records[i].life=6;//订单的菜不存在
                    s++;
                }
                return records[i];
            }
            return null;
        }//添加一条菜品信息到订单中。

        public void delARecordByOrderNum(int orderNum){
            for (i=0;i<s;i++){
                if(records[i].orderNum==orderNum){
                    if(records[i].life==1)
                        records[i].life = 2;
                    else
                        records[i].life = 1;
                }

            }

        }//根据序号删除一条记录

        public int findRecordByNum(int orderNum){
            for (i=0;i<s;i++){
                if (records[i].orderNum==orderNum)
                    return i;
            }
            return -1;
        }//根据序号查找一条记录

    }
    class Table {
        Order order;
        int num;
        int year;
        int month;
        int day;
        int shi;
        int fen;
        int miao;
        int week;
        public Table(){

        }
        public boolean check(){
            int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
            if (month >= 1 && month <= 12) {
                //判断是否为闰年
                if ((year % 100 == 0 && year % 400 == 0) || year % 4 == 0) {
                    //判断当前月份是否为2月,因为闰年的2月份为29天
                    if (month == 2 && day <= 29) return true;
                    else {
                        if (day <= days[month - 1]) return true;
                    }
                } else {
                    if (day <= days[month - 1])
                        return true;
                }
            }
            return false;
        }
        boolean checkorder(int x){//检查点菜序号
            for(int j=0;j<=order.s-1;j++){
                if(x<=order.records[j].orderNum)
                    return false;
            }
            return true;
        }

    }

(2)解释和心得
菜单计价程序-4就是菜单计价程序-3的升级版,加了特色菜,增加的异常大多其实在菜单计价程序-3也可以出现,只是没有测试点而已。两者的思路都一样,将主函数分为两部分,一部分是菜单,另一部分是点菜。

                int l = 0;
                int n = 0;
                if (!s[1].matches("[1-9]||[1-9][0-9]||[1-2][0-9][0-9]")) {
                    System.out.println("wrong format");
                    menu.dishs[menu.t] = new Dish();
                } else {
                    n = Integer.parseInt(s[1]);
                    boolean special = false;
                    if (x == 3) {
                        if(s[2].matches("T"))
                        special = true;
                       else{
                           System.out.println("wrong format");
                    System.exit(0);
                       }
                    }
                    menu.addDish(s[0], n, special);
                    if (n <= 0 || n >= 300) {//菜价超出范围
                        System.out.println(s[0] + " price out of range " + n);
                    }
                }
} else {

                t = 1;
                if(x>4){
                    System.out.println("wrong format");
                    System.exit(0);
                }
                while (true) {
                    if(f==1)
                        break;
                    y++;
                    if (x == 4 && !(s[0].matches("table")) && y == 0) {//第一个
                        System.out.println("wrong format");
                        System.exit(0);
                    }
                    while ((x == 4 && s[0].matches("table")) || y > 0) {
                        if(f==1)
                            break;
                        if (s.length == 4) {////后面的桌子直接进入点菜,后面所有的信息并入上一桌一起计算
                            tables[y] = new Table();
                            tables[y].order = new Order();
                            String[] s1 = s[2].split("/");//年月日的分割
                            String[] s2 = s[3].split("/");//时分秒的分割
                            SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd");
                            SimpleDateFormat d2 = new SimpleDateFormat("u");
                            Date date = d.parse(s1[0] + "-" + s1[1] + "-" + s1[2]);//日期格式化
                            int week = Integer.parseInt(d2.format(date));//提取星期几
                            tables[y].week = week;
                            if (!s[1].matches("\\d*")) {//检查"table"部分
                                System.out.println("wrong format");
                                if (y == 0)//第一个桌子桌号错误直接退出
                                    System.exit(0);
                                else//后面所有的信息并入上一桌一起计算
                                    y--;
                            } else {
                                tables[y].num = Integer.parseInt(s[1]);
                                tables[y].year = Integer.parseInt(s1[0]);
                                tables[y].month = Integer.parseInt(s1[1]);
                                tables[y].day = Integer.parseInt(s1[2]);
                                tables[y].shi = Integer.parseInt(s2[0]);
                                tables[y].fen = Integer.parseInt(s2[1]);
                                tables[y].miao = Integer.parseInt(s2[2]);
                                if(s[1].matches("[0].+")){
                                    System.out.println("wrong format");
                                    System.exit(0);
                                }

                                if (!(tables[y].num <= 55 && tables[y].num >= 1)) {
                                    System.out.println("table num out of range");
                                    System.exit(0);
                                }
                                else if(!tables[y].check()){
                                    System.out.println(tables[y].num+" date error");
                                    System.exit(0);
                                }
                                else if(tables[y].year>2023||tables[y].year<2022){
                                    System.out.println("not a valid time period");
                                    System.exit(0);
                                }
                                else
                                    System.out.println("table " + Integer.parseInt(s[1]) + ": ");
                            }
                        } else {
                            System.out.println("wrong format");
                            f = 0;
                            y--;//数据并入上一卓
                        }
                        for (; ; i++) {//点菜
                            if (f == 1 || f == 2)
                                break;
                            String aa = input.nextLine();
                            String[] ss = aa.split(" ");
                            //System.out.println(y + "---------" + aa);
                            if (ss.length == 4 && ss[0].charAt(0) == 't') {//新桌子
                                s = ss;
                                y++;
                                break;
                            }
                            if (ss.length == 4) {//点菜
                                //System.out.println(y+"%"+ss[0]);
                                //tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
                                if (!tables[y].checkorder(Integer.parseInt(ss[0])))//检查订单序号顺序
                                    System.out.println("record serial number sequence error");
                                else if (menu.searthDish(ss[1])==null)//订单的菜不存在
                                    System.out.println(ss[1] + " does not exist");
                                else if (Integer.parseInt(ss[2]) > 3) {//份额超过3
                                    System.out.println(ss[0] + " " + "portion out of range" + " " + ss[2]);
                                } else if (Integer.parseInt(ss[3]) > 15) {//订单大于15
                                    System.out.println(ss[0] + " " + "num out of range" + " " + ss[3]);
                                } else {
                                    tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
                                    System.out.println(ss[0] + " " + ss[1] + " " + tables[y].order.records[tables[y].order.s - 1].ygetPrice());
                                    tables[y].order.records[tables[y].order.s - 1].shi=tables[y].shi;
                                    tables[y].order.records[tables[y].order.s - 1].fen=tables[y].fen;
                                    
                                }
                            }
                            if (ss.length == 2 && ss[1].matches("delete")) {//删除
                                if(tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))==-1) {
                                    System.out.println("delete error");
                                }
                                else {

                                    tables[y].order.delARecordByOrderNum(Integer.parseInt(ss[0]));
                                    if (tables[y].order.records[tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))].life == 2) //重复删除的情况
                                        System.out.println("deduplication " + ss[0]);
                                }
                            }
                            if ((ss.length == 2 || ss.length == 3) && !ss[1].matches("delete")) {
                                System.out.println("invalid dish");
                            }
                            if (ss.length > 4) {
                                a = aa;
                                s = a.split(" ");

                                f = 2;

                            }
                           // System.out.println("////");
                        /*if(ss.length==5){//代点菜
                            for(int t=0;t<=y;t++){
                                if(ss[0].equals(tables[i].num))
                            }
                        }*/
                            if (aa.equals("end")) {
                                f = 1;
                                break;
                            }

                        }
                        if (f == 1 || f == 2)
                            break;
                    }
                    if (f == 1)
                        break;
                }
            }

题目模板给了四个类,我是把桌子又创了一个类,好像也可以放在订单类作为一种成员。

        Order order;
        int num;
        int year;
        int month;
        int day;
        int shi;
        int fen;
        int miao;
        int week;
        public Table(){

        }
        public boolean check(){
            int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
            if (month >= 1 && month <= 12) {
                //判断是否为闰年
                if ((year % 100 == 0 && year % 400 == 0) || year % 4 == 0) {
                    //判断当前月份是否为2月,因为闰年的2月份为29天
                    if (month == 2 && day <= 29) return true;
                    else {
                        if (day <= days[month - 1]) return true;
                    }
                } else {
                    if (day <= days[month - 1])
                        return true;
                }
            }
            return false;
        }
        boolean checkorder(int x){//检查点菜序号
            for(int j=0;j<=order.s-1;j++){
                if(x<=order.records[j].orderNum)
                    return false;
            }
            return true;
        }

    }
2.题目集5(7-5) 日期问题面向对象设计(聚合一)和(7-6) 日期问题面向对象设计(聚合二)

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

(7-5) 日期问题面向对象设计(聚合一)

(7-6) 日期问题面向对象设计(聚合二)

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

求下n天
求前n天
求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
(1)代码如下
(7-5) 日期问题面向对象设计(聚合一)


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());
            if (month<1||month>12) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            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);
            }
            date = date.getNextNDays(m);
            System.out.print(date.day.month.year.getValue()+"-"+date.day.month.getValue()+"-"+date.day.getValue());
        } 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());
            if (month<1||month>12) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            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);
            }
            date = date.getPreviousNDays(n);
            System.out.print(date.day.month.year.getValue()+"-"+date.day.month.getValue()+"-"+date.day.getValue());
        } 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());
            if (month<1||month>12||anotherMonth>12||anotherMonth<1) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            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 Year{
    private int value;
    public Year(){
        value = 1950;

    }
    public Year(int value){
        this.value=value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public boolean isLeapYear(){
        if(value%400==0||(value%4==0&&value%100!=0))
            return true;
        else
            return false;
    }
    public boolean validate(){
        if(value<=2050&&value>=1900)
            return true;
        else
            return false;
    }
    public void yearIncrement(){
        setValue(getValue()+1);
    }
    public void yearReduction(){
        setValue(getValue()-1);
    }
}
class Month{
    private int value;
    Year year;
    public Month(){
        year = new Year();
        value = 1;
    }
    public Month(int yearValue ,int monthValue){
        year = new Year(yearValue);
        this.value = monthValue;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setYear(Year year) {
        this.year = year;
    }

    public Year getYear() {
        return year;
    }
    public void restMin(){
        setValue(1);
    }
    public void restMax(){
        setValue(12);
    }
    public boolean validate(){
        if(value>=1&&value<=12)
            return true;
        else
            return false;
    }
    public void monthIncrement(){
        setValue(getValue()+1);
    }
    public void monthReduction(){
        setValue(getValue()-1);
    }
}
class Day{
    private int value;
    Month month;
    int[] mon_maxnum = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
    int[] mon_maxnum2 = new int[]{31,29,31,30,31,30,31,31,30,31,30,31};
    public Day(){
        month = new Month();
        value = 1;
    }
    public Day(int yearValue,int monthValue,int dayValue){
        month = new Month(yearValue,monthValue);
        value = dayValue;
    }

    public int getValue() {
        return value;
    }

    public Month getMonth() {
        return month;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public void setMonth(Month month) {
        this.month = month;
    }
    public void restMin(){
        setValue(1);
    }
    public void restMax(){
        if(month.year.isLeapYear())
        setValue(mon_maxnum2[month.getValue()-1]);
        else
            setValue(mon_maxnum[month.getValue()-1]);
    }
    public boolean validate(){
        if(month.year.isLeapYear()&&value<=mon_maxnum2[month.getValue()-1]&&value>=1)
            return true;
        else if(value<=mon_maxnum[month.getValue()-1]&&value>=1)
            return true;
        else
            return false;
    }
    public void dayIncrement(){
        setValue(getValue()+1);
    }
    public void datReduction(){
        setValue(getValue()-1);
    }
}
class DateUtil{
    Day day;
    public DateUtil(){
        day = new Day();
    }
    public DateUtil(int d,int m,int y){
        day = new Day(d,m,y);
    }

    public Day getDay() {
        return day;
    }

    public void setDay(Day day) {
        this.day = day;
    }
    public boolean checkInputValidity(){
        if(day.validate()&&day.month.validate()&&day.month.year.validate())
            return true;
        else
            return false;
    }
    public boolean compareDates(DateUtil date) {
        boolean bool = false;
        if (date.day.month.year.getValue() < day.month.year.getValue())
            bool = true;
        else if (date.day.month.year.getValue() > day.month.year.getValue())
            bool = false;
        else {
            if (date.day.month.getValue() < day.month.getValue())
                bool = true;
            else if (date.day.month.getValue() > day.month.getValue())
                bool = false;
            else {
                if (date.day.getValue() < day.getValue())
                    bool = true;
                else if (date.day.getValue() > day.getValue())
                    bool = false;
            }
        }
        return bool;
    }
    public boolean equalTwoDates(DateUtil date) {
        if (date.day.getValue()==day.getValue()&&date.day.month.getValue()==day.month.getValue()&&date.day.month.year.getValue()==day.month.year.getValue())
            return true;
        else
            return false;
    }
    public String showDate(){
        String i = day.month.year.getValue()+"-"+day.month.getValue()+"-"+day.getValue();
        return i;
    }
    public DateUtil getNextNDays(int n){
        while (true){
            if(day.month.year.isLeapYear() ){
                if (day.mon_maxnum2[day.month.getValue()-1] - day.getValue() >= n) {
                    day.setValue(day.getValue() + n);
                    n = 0;
                    break;
                } else {
                    if (day.month.getValue() != 12) {
                        n = n - (day.mon_maxnum2[day.month.getValue()-1] - day.getValue()) - 1;
                        day.month.monthIncrement();
                        day.restMin();
                    } else {
                        n = n - (day.mon_maxnum2[day.month.getValue()-1] - day.getValue()) - 1;
                        day.restMin();
                        day.month.restMin();
                        day.month.year.yearIncrement();
                    }

                }
               }
            else {
                if (day.mon_maxnum[day.month.getValue()-1] - day.getValue() >= n) {
                    day.setValue(day.getValue() + n);
                    n = 0;
                    break;
                } else {
                    if (day.month.getValue() != 12) {
                        n = n - (day.mon_maxnum[day.month.getValue()-1] - day.getValue())-1;
                        day.month.monthIncrement();
                        day.restMin();
                    } else {
                        n = n - (day.mon_maxnum[day.month.getValue()-1] - day.getValue())-1;
                        day.restMin();
                        day.month.restMin();
                        day.month.year.yearIncrement();
                    }

                }
            }

        }
        DateUtil date1 = new DateUtil(this.day.month.year.getValue(), this.day.month.getValue(), this.day.getValue());
        return date1;

    }

    public DateUtil getPreviousNDays(int n){
        while(true){
            if(n>=day.getValue()){
                if(day.month.getValue()>1) {
                    n=n-day.getValue();
                    day.month.monthReduction();
                        day.restMax();

                }
                else {
                    day.month.restMax();
                    day.month.year.yearReduction();
                    n=n-day.getValue();
                    day.restMax();}

            }
            else {
                day.setValue(day.getValue()-n);
                break;
            }
        }
        DateUtil date2 = new DateUtil(day.month.year.getValue(), day.month.getValue(), day.getValue());
        return date2;

    }

    public int num2(DateUtil date){
        int s = 0;
        int i;
        for ( i = 1; i < date.day.month.year.getValue(); i++) {
            if ((i%400==0||(i%100!=0&&i%4==0)))
                s = s + 366;
            else
                s = s + 365;
        }
        for (int j = 1; j < date.day.month.getValue(); j++) {
            if ((i%400==0||(i%4==0&&i%100!=0))&&j==2)
                s = s+date.day.mon_maxnum[j-1]+1;
            else
                s = s+date.day.mon_maxnum[j-1];
        }
        s = s + date.day.getValue();
        return s;
    }
    public int num1(Day day){
        int s = 0;
        int i;
        for ( i = 1; i < day.month.year.getValue(); i++) {
            if (i%400==0||(i%100!=0&&i%4==0))
                s = s + 366;
            else
                s = s + 365;
        }
        for (int j = 1; j < day.month.getValue(); j++) {
            if((i%400==0||(i%100!=0&&i%4==0))&&j==2)
            s = s+day.mon_maxnum[j-1]+1;
            else
            s = s+day.mon_maxnum[j-1];
        }
        s = s + day.getValue();
        return s;
    }
    public int getDaysofDates(DateUtil date)
    {
        int s = num1( day) -num2(date);
        if (s < 0)
            s = -s;
        return s;
    }
}

(7-6) 日期问题面向对象设计(聚合二)


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());
            if (month<1||month>12) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            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.showDate()+" next "+m+" days is:"+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());
            if (month<1||month>12) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            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.showDate()+" previous "+n+" days is:"+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());
            if (month<1||month>12||anotherMonth>12||anotherMonth<1) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            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 Year{
    private int value;
    public Year(){
        value = 1950;

    }
    public Year(int value){
        this.value=value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public boolean isLeapYear(){
        if(value%400==0||(value%4==0&&value%100!=0))
            return true;
        else
            return false;
    }
    public boolean validate(){
        if(value<=2020&&value>=1820)
            return true;
        else
            return false;
    }
    public void yearIncrement(){
        setValue(getValue()+1);
    }
    public void yearReduction(){
        setValue(getValue()-1);
    }
}
class Month{
    private int value;
    public Month(){
        value = 1;
    }
    public Month(int monthValue){
        this.value = monthValue;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
    public void restMin(){
        setValue(1);
    }
    public void restMax(){
        setValue(12);
    }
    public boolean validate(){
        if(value>=1&&value<=12)
            return true;
        else
            return false;
    }
    public void monthIncrement(){
        setValue(getValue()+1);
    }
    public void monthReduction(){
        setValue(getValue()-1);
    }
}
class Day{
    private int value;
    public Day(){
        value = 1;
    }
    public Day(int dayValue){
        value = dayValue;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
    public void dayIncrement(){
        setValue(getValue()+1);
    }
    public void datReduction(){
        setValue(getValue()-1);
    }
}
class DateUtil{
    Day day;
    Month month;
    Year year;
    int[] mon_maxnum = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    int[] mon_maxnum2 = new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};
    public DateUtil(){
        day = new Day();
        month = new Month();
        year = new Year();
    }
    public DateUtil(int y,int m,int d){
        day = new Day(d);
        month = new Month(m);
        year = new Year(y);
    }

    public Day getDay() {
        return day;
    }

    public Month getMonth() {
        return month;
    }

    public Year getYear() {
        return year;
    }

    public void setDay(Day day) {
        this.day = day;
    }

    public void setMonth(Month month) {
        this.month = month;
    }

    public void setYear(Year year) {
        this.year = year;
    }
    public void setDayMin() {
        day.setValue(1);
    }
    public void setDayMax(){
        if(year.isLeapYear())
            day.setValue(mon_maxnum2[month.getValue()]);
        else
            day.setValue(mon_maxnum[month.getValue()]);
    }

    public boolean checkInputValidity(){
        if(year.isLeapYear()){
            if (day.getValue()>=1&&day.getValue()<=mon_maxnum2[month.getValue()]&& month.validate()&&year.validate())
                return true;
            else
                return false;
        }
        else {
            if (day.getValue() >= 1 && day.getValue() <= mon_maxnum[month.getValue()] && month.validate() && year.validate())
                return true;
            else
                return false;
        }

    }
    public DateUtil getNextNDays(int n){
        while (true){
            if(year.isLeapYear() ){
                if (mon_maxnum2[month.getValue()] - day.getValue() >= n) {
                    day.setValue(day.getValue() + n);
                    n = 0;
                    break;
                } else {
                    if (month.getValue() != 12) {
                        n = n - (mon_maxnum2[month.getValue()] - day.getValue()) - 1;
                        month.monthIncrement();
                        setDayMin();
                    } else {
                        n = n - (mon_maxnum2[month.getValue()] - day.getValue()) - 1;
                        setDayMin();
                        month.restMin();
                        year.yearIncrement();
                    }

                }
            }
            else {
                if (mon_maxnum[month.getValue()] - day.getValue() >= n) {
                    day.setValue(day.getValue() + n);
                    n = 0;
                    break;
                } else {
                    if (month.getValue() != 12) {
                        n = n - (mon_maxnum[month.getValue()] - day.getValue())-1;
                        month.monthIncrement();
                        setDayMin();
                    } else {
                        n = n - (mon_maxnum[month.getValue()] - day.getValue())-1;
                        setDayMin();
                        month.restMin();
                        year.yearIncrement();
                    }

                }
            }

        }
        DateUtil date1 = new DateUtil(this.year.getValue(), this.month.getValue(), this.day.getValue());
        return date1;

    }

    public DateUtil getPreviousNDays(int n){
        while(true){
            if(n>=day.getValue()){
                if(month.getValue()>1) {
                    n=n-day.getValue();
                    month.monthReduction();
                    setDayMax();

                }
                else {
                    month.restMax();
                    year.yearReduction();
                    n=n-day.getValue();
                    setDayMax();}

            }
            else {
                day.setValue(day.getValue()-n);
                break;
            }
        }
        DateUtil date2 = new DateUtil(year.getValue(), month.getValue(), day.getValue());
        return date2;

    }
    public boolean compareDates(DateUtil date) {
        if(num1()>num2(date))
            return true;
        else
            return false;
    }
    public boolean equalTwoDates(DateUtil date) {
        if (num1()==num2(date))
            return true;
        else
            return false;
    }



    public int num2(DateUtil date){
        int s = 0;
        int i;
        for ( i = 1; i < date.year.getValue(); i++) {
            if ((i%400==0||(i%100!=0&&i%4==0)))
                s = s + 366;
            else
                s = s + 365;
        }
        for (int j = 1; j < date.month.getValue(); j++) {
            if ((i%400==0||(i%4==0&&i%100!=0))&&j==2)
                s = s+date.mon_maxnum[j]+1;
            else
                s = s+date.mon_maxnum[j];
        }
        s = s + date.day.getValue();
        return s;
    }
    public int num1(){
        int s = 0;
        int i;
        for ( i = 1; i < year.getValue(); i++) {
            if (i%400==0||(i%100!=0&&i%4==0))
                s = s + 366;
            else
                s = s + 365;
        }
        for (int j = 1; j < month.getValue(); j++) {
            if((i%400==0||(i%100!=0&&i%4==0))&&j==2)
                s = s+mon_maxnum[j]+1;
            else
                s = s+mon_maxnum[j];
        }
        s = s + day.getValue();
        return s;
    }
    public int getDaysofDates(DateUtil date)
    {
        int s = num1() -num2(date);
        if (s < 0)
            s = -s;
        return s;
    }
    public String showDate(){
        String i = year.getValue()+"-"+month.getValue()+"-"+day.getValue();
        return i;
    }
}

(2)解释与心得
这两道题在前面的题目集3(7-4) 日期类设计做过,只不过这回是根据类图来还原代码,两道题的不同在于:聚合一是几个类一个跟一个的链状结构聚合,Month和Year之间是聚合关系,Day和Month之间是聚合关系,DateUtil和Day之间是聚合关系;聚合二是一个类和其他所有类的聚合DateUtil和Day,Month,Year之间是聚合关系。编程难度跟之前差不多,只是细分出了更多的方法,照着类图编程就行。


三.踩坑心得

这几次题目集最麻烦的就是菜单计价程序-4,题目本身并不需要用什么新方法,但是题目要求的东西非常多,错误类型多种多样,测试点有45个之多,开始写代码前要把各种错误情况和测试点的提示都看一遍。我就是没有弄明白就开写导致三次大规模重写。像把输出放最后;像写到后面桌子不知道怎么处理只能推倒前面的又创建新的类。复杂的程序一定要先把结构和功能想好再动手。


四.改进建议

菜单计价程序要先把输入的数据全部检查再进行处理


五.总结

动手前先动脑,之前习惯先写一点再边理解题目边写,觉得慢慢改也没什么,结果这次的菜单计价程序吃大亏了。类之间的结构多种多样,各有各的有缺点,可以根据需求调整结构。学会了正则表达式,在检查数据时非常有用。

posted @ 2023-04-28 00:01  王予琦  阅读(245)  评论(0)    收藏  举报