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个之多,开始写代码前要把各种错误情况和测试点的提示都看一遍。我就是没有弄明白就开写导致三次大规模重写。像把输出放最后;像写到后面桌子不知道怎么处理只能推倒前面的又创建新的类。复杂的程序一定要先把结构和功能想好再动手。
四.改进建议
菜单计价程序要先把输入的数据全部检查再进行处理
五.总结
动手前先动脑,之前习惯先写一点再边理解题目边写,觉得慢慢改也没什么,结果这次的菜单计价程序吃大亏了。类之间的结构多种多样,各有各的有缺点,可以根据需求调整结构。学会了正则表达式,在检查数据时非常有用。