4~6次java作业总结
(1)前言
这三次的作业难度相较于上次要高得多,题目集1共有7道题目,第二题和第三题之前做过,第一题的难度最大,涉及到对封装性的考查。题目集2共有6道题目,第一,三,四题均考查对正则表达式的运用,第五和第六题是之前题目的迭代,这两题中类与类之间的关系是不同的。题目集3只有一道题目,是题目集1第一题的迭代,难度很大。这三次的题目题目量下降,但难度升高,让我做的十分吃力。
(2)设计与分析
第四次作业
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"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
代码展示: 
1 package Test; 2 3 import java.util.Scanner; 4 import java.util.ArrayList; 5 public class Main{ 6 public static void main(String args[]){ 7 int i = 0,flag1 = 0,flag2 = 0,flag3 = 0; 8 Scanner input = new Scanner(System.in); 9 Menu menu = new Menu(); 10 String dishInfo = input.nextLine(); 11 while(!dishInfo.contains("table")){ 12 String[] dish = dishInfo.split(" "); 13 int price = Integer.parseInt(dish[1]); 14 menu.addDish(dish[0],price); 15 dishInfo = input.nextLine(); 16 } 17 String[] orderInfo = dishInfo.split(" "); 18 Table table = new Table(orderInfo[1],orderInfo[2],orderInfo[3]); 19 if(orderInfo[1].matches("[1-9][\\d]?")) { 20 flag2 = 1; 21 } 22 Order order = new Order(); 23 String records = input.nextLine(); 24 while(!records.equals("end")&&!records.contains("delete")){ 25 String[] record = records.split(" "); 26 if(record.length == 4) { 27 int ordernum = Integer.parseInt(record[0]); 28 int portion = Integer.parseInt(record[2]); 29 int num = Integer.parseInt(record[3]); 30 order.addARecord(ordernum,menu.searthDish(record[1]),portion,num); 31 } 32 else flag3 = 1; 33 records = input.nextLine(); 34 } 35 while(!records.equals("end")) { 36 if(order.findRecordByNum(records.charAt(0))) { 37 order.delARecordByOrderNum(records.charAt(0)); 38 flag1 = 1; 39 } 40 else flag1 = 0; 41 records = input.nextLine(); 42 } 43 if(flag2 == 1&&flag3 == 0) { 44 System.out.println("table "+table.tableNum+":"); 45 for(i = 0;i < order.records.size();i++) { 46 order.records.get(i).showRecord(); 47 } 48 System.out.println("table "+table.tableNum+": "+order.getTotalPrice()); 49 } 50 else System.out.println("wrong format"); 51 } 52 } 53 class Table{ 54 String tableNum;//桌子序号 55 String date; 56 String time; 57 58 public Table(){ 59 60 } 61 public Table(String tableNum,String date,String time){ 62 this.tableNum = tableNum; 63 this.date = date; 64 this.time = time; 65 } 66 // String[] dateInfo = date.split("/"); 67 // String[] timeInfo = time.split("/"); 68 // int num = Integer.parseInt(tableNum); 69 // int[] dInfo = new int[3]; 70 // int[] tInfo = new int[3]; 71 // for(i = 0;i < 3;i++){ 72 // dInfo[i] = Integer.parseInt(dateInfo[i]); 73 // tInfo[i] = Integer.parseInt(timeInfo[i]); 74 // } 75 } 76 class Dish{ 77 String name;//菜名 78 int unit_price;//菜品单价 79 public Dish(){ 80 81 } 82 public Dish(String name,int unit_price){ 83 this.name = name; 84 this.unit_price = unit_price; 85 } 86 public String getName(){ 87 return name; 88 } 89 public void setName(String name){ 90 this.name = name; 91 } 92 public int getPrice(int portion){ 93 int price = 0; 94 if(portion == 1){ 95 price = (int)unit_price; 96 } 97 else if(portion == 2){ 98 price = (int)(1.5*unit_price); 99 } 100 else if(portion == 3){ 101 price = (int)(2*unit_price); 102 } 103 return price; 104 } 105 } 106 class Menu{ 107 ArrayList<Dish> dishs = new ArrayList<>(); 108 public Menu(){ 109 110 } 111 int i = 0,k = 0; 112 Dish searthDish(String dishName){ 113 for(i = 0;i < dishs.size();i++) 114 if((dishs.get(i).name).equals(dishName)){ 115 k = i;break; 116 } 117 return dishs.get(k); 118 } 119 void addDish(String dishName,int unit_price){ 120 Dish dish = new Dish(dishName,unit_price); 121 dishs.add(dish); 122 } 123 } 124 class Record{ 125 int orderNum;//序号 126 Dish d;//菜品 127 int portion;//份额 128 int num;//份数 129 public Record(){ 130 131 } 132 public Record(int orderNum,Dish d,int portion,int num){ 133 this.orderNum = orderNum; 134 this.d = d; 135 this.portion = portion; 136 this.num = num; 137 } 138 int getPrice(){//计价,计算本条记录的价格 139 return d.getPrice(portion)*num; 140 } 141 public void showRecord() { 142 System.out.println(orderNum+" "+d.name+" "+getPrice()); 143 } 144 } 145 class Order { 146 int totalprice = 0; 147 int i = 0,k = 0; 148 ArrayList<Record> records = new ArrayList<>(); 149 int getTotalPrice(){//计算订单的总价 150 for(i = 0;i < records.size();i++) 151 totalprice += records.get(i).getPrice(); 152 return totalprice; 153 } 154 void addARecord(int orderNum,Dish d,int portion,int num){ 155 156 Record record = new Record(orderNum,d,portion,num); 157 records.add(record); 158 }//添加一条菜品信息到订单中。 159 160 void delARecordByOrderNum(int orderNum){ 161 records.remove(orderNum-1); 162 }//根据序号删除一条记录 163 164 boolean findRecordByNum(int orderNum){//根据序号查找一条记录 165 for(i = 0;i < records.size();i++) 166 if(records.get(i).orderNum == orderNum){ 167 break; 168 } 169 if(i == records.size()) { 170 return false; 171 } 172 else return true; 173 } 174 }
类图如下:

报表内容如下:


分析如下:
1.本题主要考查对类的创建以及类与类间关系的梳理,本题主要难点是输入输出,逻辑并不难,需要对不同的输入给出不同的输出输入和输出的情况很多。
2.通过类图可以看出类与类间的关系主要是依赖,它们之间的关系并不复杂。
3.根据题目要求,需要创建Order类,Record类,Dish类,Menu类,除此之外我还添加了Table类和Main类。
第五次作业
参考题目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
代码展示:
 
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner input = new Scanner(System.in); 6 int year = 0; 7 int month = 0; 8 int day = 0; 9 10 int choice = input.nextInt(); 11 12 if (choice == 1) { // test getNextNDays method 13 int m = 0; 14 year = Integer.parseInt(input.next()); 15 month = Integer.parseInt(input.next()); 16 day = Integer.parseInt(input.next()); 17 18 DateUtil date = new DateUtil(day,month,year); 19 20 if (!date.checkInputValidity()) { 21 System.out.println("Wrong Format"); 22 System.exit(0); 23 } 24 m = input.nextInt(); 25 if (m < 0) { 26 System.out.println("Wrong Format"); 27 System.exit(0); 28 } 29 System.out.println(date.getNextNDays(m).showDate()); 30 31 } 32 else if (choice == 2) { // test getPreviousNDays method 33 int n = 0; 34 year = Integer.parseInt(input.next()); 35 month = Integer.parseInt(input.next()); 36 day = Integer.parseInt(input.next()); 37 38 DateUtil date = new DateUtil(day,month,year); 39 40 if (!date.checkInputValidity()) { 41 System.out.println("Wrong Format"); 42 System.exit(0); 43 } 44 45 n = input.nextInt(); 46 47 if (n < 0) { 48 System.out.println("Wrong Format"); 49 System.exit(0); 50 } 51 System.out.println(date.getPreviousNDays(n).showDate()); 52 53 } 54 else if (choice == 3) { //test getDaysofDates method 55 year = Integer.parseInt(input.next()); 56 month = Integer.parseInt(input.next()); 57 day = Integer.parseInt(input.next()); 58 59 int anotherYear = Integer.parseInt(input.next()); 60 int anotherMonth = Integer.parseInt(input.next()); 61 int anotherDay = Integer.parseInt(input.next()); 62 63 DateUtil fromDate = new DateUtil(day, month, year); 64 DateUtil toDate = new DateUtil(anotherDay, anotherMonth, anotherYear); 65 66 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 67 // System.out.println("The days between " + fromDate.showDate() + 68 // " and " + toDate.showDate() + " are:" 69 // + fromDate.getDaysofDates(toDate)); 70 System.out.println(fromDate.getDaysofDates(toDate)); 71 } else { 72 System.out.println("Wrong Format"); 73 System.exit(0); 74 } 75 } 76 77 else{ 78 System.out.println("Wrong Format"); 79 System.exit(0); 80 } 81 } 82 } 83 84 class DateUtil{ 85 private Day day = new Day(); 86 87 public DateUtil(){ 88 89 } 90 public DateUtil(int d,int m,int y){ 91 this.day.setValue(d); 92 this.day.getMonth().setValue(m); 93 this.day.getMonth().getYear().setValue(y); 94 } 95 public Day getDay(){ 96 return day; 97 } 98 public void setDay(int d){ 99 this.day.setValue(d); 100 } 101 public boolean checkInputValidity(){ 102 int flag1 = 0,flag2 = 0,flag3 = 0; 103 if(day.getMonth().getYear().getValue()>=1900&& 104 day.getMonth().getYear().getValue()<=2050&& 105 day.getMonth().getValue()>=1&& 106 day.getMonth().getValue()<=12&& 107 day.getValue()>=1&&day.getValue()<=31){ 108 flag1 = 1; 109 } 110 if(day.getMonth().getValue() == 2) 111 { 112 if((day.getMonth().getYear().isLeapYear()&&day.getValue() > 29) 113 ||(!day.getMonth().getYear().isLeapYear()&&day.getValue() > 28)) { 114 flag2 = 1; 115 } 116 } 117 else if(day.getMonth().getValue() == 4|| 118 day.getMonth().getValue() == 6|| 119 day.getMonth().getValue() == 9|| 120 day.getMonth().getValue() == 11){ 121 if(day.getValue() > 30){ 122 flag3 = 1; 123 } 124 } 125 if(flag1 == 1&&flag2 == 0&&flag3 == 0) { 126 return true; 127 } 128 else return false; 129 } 130 public boolean compareDates(DateUtil date){ 131 if(day.getMonth().getYear().getValue()> 132 date.day.getMonth().getYear().getValue()) 133 return true; 134 else if(day.getMonth().getYear().getValue()== 135 date.day.getMonth().getYear().getValue()){ 136 if(day.getMonth().getValue()> 137 date.day.getMonth().getValue()) 138 return true; 139 else if(day.getMonth().getValue()== 140 date.day.getMonth().getValue()){ 141 if(day.getValue()>date.day.getValue()) return true; 142 else if(day.getValue()==date.day.getValue()) return true; 143 else return false; 144 } 145 else return false; 146 } 147 else return false; 148 } 149 public boolean equalTwoDates(DateUtil date){ 150 if(day.getMonth().getYear().getValue()== 151 date.day.getMonth().getYear().getValue()&& 152 day.getMonth().getValue()==date.day.getMonth().getValue()&& 153 day.getValue() == date.day.getValue()) 154 return true; 155 else return false; 156 } 157 public String showDate(){ 158 String s=day.getMonth().getYear().getValue()+"-"+ 159 day.getMonth().getValue()+"-"+day.getValue(); 160 return s; 161 } 162 public DateUtil getNextNDays(int n){ 163 int i = 0; 164 for(i = 0;i < n;i++){ 165 switch(day.getMonth().getValue()){ 166 case 2: 167 if(day.getMonth().getYear().isLeapYear()){ 168 if(day.getValue()>29) System.out.print("Wrong Format"); 169 else if(day.getValue()==29){day.getMonth().monthIrement();day.resetMin();} 170 else if(day.getValue()<29){day.dayIrement();} 171 } 172 else { 173 if(day.getValue()>28) System.out.print("Wrong Format"); 174 else if(day.getValue()==28){day.getMonth().monthIrement();day.resetMin();} 175 else if(day.getValue()<28){day.dayIrement();} 176 } 177 break; 178 case 1: 179 case 3: 180 case 5: 181 case 7: 182 case 8: 183 case 10: 184 if(day.getValue()==31){day.getMonth().monthIrement();day.resetMin();} 185 else if(day.getValue()<31){day.dayIrement();} 186 break; 187 case 4: 188 case 6: 189 case 9: 190 case 11: 191 if(day.getValue()==30){day.getMonth().monthIrement();day.resetMin();} 192 else if(day.getValue()<30){day.dayIrement();} 193 break; 194 case 12: 195 if(day.getValue()==31){day.getMonth().getYear().yearIrement();day.getMonth().resetMin();day.resetMin();} 196 else if(day.getValue()<31){day.dayIrement();} 197 break; 198 } 199 } 200 DateUtil date1 = new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue()); 201 return date1; 202 } 203 204 205 public DateUtil getPreviousNDays(int n){ 206 int i; 207 for(i = 0;i < n;i++){ 208 switch(day.getMonth().getValue()){ 209 case 2: 210 if(day.getMonth().getYear().isLeapYear()){ 211 // if(day.getValue()>29)System.out.print("Wrong Format"); 212 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 213 else {day.dayReduction();} 214 } 215 else { 216 // if(day.getValue()>28)System.out.print("Wrong Format"); 217 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 218 else {day.dayReduction();} 219 } 220 break; 221 case 1: 222 if(day.getValue()==1){day.getMonth().getYear().yearReduction();day.getMonth().resetMax();day.resetMax();} 223 else {day.dayReduction();} 224 break; 225 case 3: 226 if(day.getValue()==1){ 227 if(day.getMonth().getYear().isLeapYear()){ 228 day.getMonth().monthReduction();day.setValue(29); 229 } 230 else {day.getMonth().monthReduction();day.setValue(28);} 231 } 232 else {day.dayReduction();} 233 break; 234 case 5: 235 case 7: 236 case 10: 237 case 12: 238 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 239 else {day.dayReduction();} 240 break; 241 case 4: 242 case 6: 243 case 8: 244 case 9: 245 case 11: 246 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 247 else {day.dayReduction();} 248 break; 249 } 250 } 251 DateUtil date2 = new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue()); 252 return date2; 253 } 254 public int getDaysofDates(DateUtil date){ 255 int d=0; 256 if(equalTwoDates(date)) return d; 257 else { 258 if(!compareDates(date)){//新输入的日期大于当前日期 259 while(!equalTwoDates(date)){//往下加一天,并比较一次,直到两日期相同 260 switch(day.getMonth().getValue()){ 261 case 2: 262 if(day.getMonth().getYear().isLeapYear()){ 263 if(day.getValue()==29){day.getMonth().monthIrement();day.resetMin();} 264 else if(day.getValue()<29){day.dayIrement();} 265 } 266 else { 267 if(day.getValue()==28){day.getMonth().monthIrement();day.resetMin();} 268 else if(day.getValue()<28){day.dayIrement();} 269 } 270 break; 271 case 1: 272 case 3: 273 case 5: 274 case 7: 275 case 8: 276 case 10: 277 if(day.getValue()==31){day.getMonth().monthIrement();day.resetMin();} 278 else if(day.getValue()<31){day.dayIrement();} 279 break; 280 case 4: 281 case 6: 282 case 9: 283 case 11: 284 if(day.getValue()==30){day.getMonth().monthIrement();day.resetMin();} 285 else if(day.getValue()<30){day.dayIrement();} 286 break; 287 case 12: 288 if(day.getValue()==31){day.getMonth().getYear().yearIrement();day.getMonth().resetMin();day.resetMin();} 289 else if(day.getValue()<31){day.dayIrement();} 290 break; 291 } 292 d++; 293 } 294 } 295 else{//新输入的日期小于当前日期 296 while(!equalTwoDates(date)){//让当前日期减小,直到与新日期相同 297 switch(day.getMonth().getValue()){ 298 case 2: 299 if(day.getMonth().getYear().isLeapYear()){ 300 // if(day.getValue()>29)System.out.print("Wrong Format"); 301 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 302 else {day.dayReduction();} 303 } 304 else { 305 // if(day.getValue()>28)System.out.print("Wrong Format"); 306 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 307 else {day.dayReduction();} 308 } 309 break; 310 case 1: 311 if(day.getValue()==1){day.getMonth().getYear().yearReduction();day.getMonth().resetMax();day.resetMax();} 312 else {day.dayReduction();} 313 break; 314 case 3: 315 if(day.getValue()==1){ 316 if(day.getMonth().getYear().isLeapYear()){ 317 day.getMonth().monthReduction();day.setValue(29); 318 } 319 else {day.getMonth().monthReduction();day.setValue(28);} 320 } 321 else {day.dayReduction();} 322 break; 323 case 5: 324 case 7: 325 case 10: 326 case 12: 327 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 328 else {day.dayReduction();} 329 break; 330 case 4: 331 case 6: 332 case 8: 333 case 9: 334 case 11: 335 if(day.getValue()==1){day.getMonth().monthReduction();day.resetMax();} 336 else {day.dayReduction();} 337 break; 338 } 339 d++; 340 } 341 342 } 343 } 344 return d; 345 } 346 } 347 class Day{ 348 private int value; 349 private Month month= new Month(); 350 private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31}; 351 352 public Day(){ 353 354 } 355 public Day(int yearValue,int monthValue,int dayValue){ 356 this.month.getYear().setValue(yearValue); 357 this.month.setValue(monthValue); 358 this.value = dayValue; 359 } 360 public int getValue(){ 361 return value; 362 } 363 public void setValue(int value){ 364 this.value = value; 365 } 366 public Month getMonth(){ 367 return month; 368 } 369 public void setMonth(Month month){ 370 this.month = month; 371 } 372 public void resetMin(){ 373 value = 1; 374 } 375 public void resetMax(){ 376 value = mon_maxnum[month.getValue() - 1]; 377 } 378 public boolean validate(){ 379 if(value >= 1||value <= 31) 380 return true; 381 else return false; 382 } 383 public void dayIrement(){ 384 value++; 385 } 386 public void dayReduction(){ 387 value--; 388 } 389 } 390 class Month{ 391 private int value; 392 private Year year = new Year(); 393 394 public Month(){ 395 396 } 397 public Month(int yearValue,int monthValue){ 398 this.year.setValue(yearValue); 399 this.value = monthValue; 400 } 401 public int getValue(){ 402 return value; 403 } 404 public void setValue(int value){ 405 this.value = value; 406 } 407 public Year getYear(){ 408 return year; 409 } 410 public void setYear(Year year){ 411 this.year = year; 412 } 413 public void resetMin(){ 414 value = 1; 415 } 416 public void resetMax(){ 417 value = 12; 418 } 419 public boolean validate(){ 420 if(value >= 1||value <= 12) 421 return true; 422 else return false; 423 } 424 public void monthIrement(){ 425 value++; 426 } 427 public void monthReduction(){ 428 value--; 429 } 430 } 431 class Year{ 432 private int value; 433 434 public Year(){ 435 436 } 437 public Year(int value){ 438 this.value = value; 439 } 440 public int getValue(){ 441 return value; 442 } 443 public void setValue(int value){ 444 this.value = value; 445 } 446 public boolean isLeapYear(){ 447 if((value%4==0&&value%100!=0)||value%400==0){ 448 return true; 449 } 450 else return false; 451 } 452 public boolean validate(){ 453 if(value >= 1900||value <= 2050) 454 return true; 455 else return false; 456 } 457 public void yearIrement(){ 458 value++; 459 } 460 public void yearReduction(){ 461 value--; 462 } 463 }
类图如下:

报表内容如下:



分析如下:
1.本题是之前题目集的迭代,做起来相对轻松一些。
2.本题要求根据题目集中给出的类图编写程序。从题目中给出的类图可以看出,需要创建五个类,其中除了主类外的四个类之间的关系是聚合。
3.除此之外,还需要注意封装性,类的属性是私有的,类的方法是公开的。
4.由于我将五个类的程序都写在同一个java文件中,所以我生成的类图与题目不同,分成多个文件后的类图如下:

参考题目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
代码展示:
 
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(day,month,year); 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.getYear().getValue() + "-" + date.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(day,month,year); 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.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().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(day, month, year); DateUtil toDate = new DateUtil(anotherDay, anotherMonth, anotherYear); if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:" + fromDate.getDaysofDates(toDate)); // 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 Year year = new Year(); private Month month = new Month(); private Day day = new Day(); private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil(){ } public DateUtil(int d,int m,int y){ this.day.setValue(d); this.month.setValue(m); this.year.setValue(y); } 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(){ day.setValue(mon_maxnum[month.getValue()-1]); } public boolean checkInputValidity(){ int flag1 = 0,flag2 = 0; if(year.getValue()>=1820&& year.getValue()<=2020&& month.getValue()>=1&& month.getValue()<=12&& day.getValue()>=1&&day.getValue()<=31){ flag1 = 1; } if(month.getValue() == 2) { if((year.isLeapYear()&&day.getValue() > 29) ||(!year.isLeapYear()&&day.getValue() > 28)) { flag2 = 1; } } if(flag1 == 1&&flag2 == 0) { return true; } else return false; } public boolean compareDates(DateUtil date){ if(year.getValue()> date.year.getValue()) return true; else if(year.getValue()== date.year.getValue()){ if(month.getValue()> date.month.getValue()) return true; else if(month.getValue()== date.month.getValue()){ if(day.getValue()>date.day.getValue()) return true; else if(day.getValue()==date.day.getValue()) return true; else return false; } else return false; } else return false; } public boolean equalTwoDates(DateUtil date){ if(year.getValue()== date.year.getValue()&& month.getValue()==date.month.getValue()&& day.getValue() == date.day.getValue()) return true; else return false; } public String showDate(){ String s=year.getValue()+"-"+ month.getValue()+"-"+day.getValue(); return s; } public DateUtil getNextNDays(int n){ int i = 0; for(i = 0;i < n;i++){ switch(month.getValue()){ case 2: if(year.isLeapYear()){ if(day.getValue()>29) System.out.print("Wrong Format"); else if(day.getValue()==29){month.monthIrement();setDayMin();} else if(day.getValue()<29){day.dayIrement();} } else { if(day.getValue()>28) System.out.print("Wrong Format"); else if(day.getValue()==28){month.monthIrement();setDayMin();} else if(day.getValue()<28){day.dayIrement();} } break; case 1: case 3: case 5: case 7: case 8: case 10: if(day.getValue()==31){month.monthIrement();setDayMin();} else if(day.getValue()<31){day.dayIrement();} break; case 4: case 6: case 9: case 11: if(day.getValue()==30){month.monthIrement();setDayMin();} else if(day.getValue()<30){day.dayIrement();} break; case 12: if(day.getValue()==31){year.yearIrement();month.resetMin();setDayMin();} else if(day.getValue()<31){day.dayIrement();} break; } } DateUtil date1 = new DateUtil(day.getValue(),month.getValue(),year.getValue()); return date1; } public DateUtil getPreviousNDays(int n){ int i; for(i = 0;i < n;i++){ switch(month.getValue()){ case 2: if(year.isLeapYear()){ // if(day.getValue()>29)System.out.print("Wrong Format"); if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} } else { // if(day.getValue()>28)System.out.print("Wrong Format"); if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} } break; case 1: if(day.getValue()==1){year.yearReduction();month.resetMax();setDayMax();} else {day.dayReduction();} break; case 3: if(day.getValue()==1){ if(year.isLeapYear()){ month.monthReduction();day.setValue(29); } else {month.monthReduction();day.setValue(28);} } else {day.dayReduction();} break; case 5: case 7: case 10: case 12: if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} break; case 4: case 6: case 8: case 9: case 11: if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} break; } } DateUtil date2 = new DateUtil(day.getValue(),month.getValue(),year.getValue()); return date2; } public int getDaysofDates(DateUtil date){ int d=0; if(equalTwoDates(date)) return d; else { if(!compareDates(date)){//新输入的日期大于当前日期 while(!equalTwoDates(date)){//往下加一天,并比较一次,直到两日期相同 switch(month.getValue()){ case 2: if(year.isLeapYear()){ if(day.getValue()>29) System.out.print("Wrong Format"); else if(day.getValue()==29){month.monthIrement();setDayMin();} else if(day.getValue()<29){day.dayIrement();} } else { if(day.getValue()>28) System.out.print("Wrong Format"); else if(day.getValue()==28){month.monthIrement();setDayMin();} else if(day.getValue()<28){day.dayIrement();} } break; case 1: case 3: case 5: case 7: case 8: case 10: if(day.getValue()==31){month.monthIrement();setDayMin();} else if(day.getValue()<31){day.dayIrement();} break; case 4: case 6: case 9: case 11: if(day.getValue()==30){month.monthIrement();setDayMin();} else if(day.getValue()<30){day.dayIrement();} break; case 12: if(day.getValue()==31){year.yearIrement();month.resetMin();setDayMin();} else if(day.getValue()<31){day.dayIrement();} break; } d++; } } else{//新输入的日期小于当前日期 while(!equalTwoDates(date)){//让当前日期减小,直到与新日期相同 switch(month.getValue()){ case 2: if(year.isLeapYear()){ // if(day.getValue()>29)System.out.print("Wrong Format"); if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} } else { // if(day.getValue()>28)System.out.print("Wrong Format"); if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} } break; case 1: if(day.getValue()==1){year.yearReduction();month.resetMax();setDayMax();} else {day.dayReduction();} break; case 3: if(day.getValue()==1){ if(year.isLeapYear()){ month.monthReduction();day.setValue(29); } else {month.monthReduction();day.setValue(28);} } else {day.dayReduction();} break; case 5: case 7: case 10: case 12: if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} break; case 4: case 6: case 8: case 9: case 11: if(day.getValue()==1){month.monthReduction();setDayMax();} else {day.dayReduction();} break; } d++; } } } return d; } } 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 >= 1820||value <= 2020) return true; else return false; } public void yearIrement(){ value++; } public void yearReduction(){ value--; } } class Month{ private int value; public Month(){ } public Month(int value){ this.value = value; } public int getValue(){ return value; } public void setValue(int value){ this.value = value; } public void resetMin(){ this.value = 1; } public void resetMax(){ this.value = 12; } public boolean validate(){ if(value >= 1||value <= 12) return true; else return false; } public void monthIrement(){ value++; } public void monthReduction(){ value--; } } class Day{ private int value; public Day(){ } public Day(int value){ this.value = value; } public int getValue(){ return value; } public void setValue(int value){ this.value = value; } public void dayIrement(){ value++; } public void dayReduction(){ value--; } }
类图如下:

报表内容如下:



分析如下:
1.本题和上题相似,算法和之前相差不大,但类图与上题不同。
2.主类依赖于DateUtil类,其他三个类于DateUtil类为聚合关系。这种类图关系较于上次更为合理。
第六次作业
本体大部分内容与菜单计价程序-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
代码展示:
 
1 import java.util.Scanner; 2 import java.util.ArrayList; 3 public class Main{ 4 public static void main(String args[]){ 5 int i = 0,j = 0,k = 0,a = 0,flag = 0,flag1 = 0,flag2 = 0,flag3 = 0,flag4 = 0; 6 int dishNum = 0; 7 ArrayList<Integer> deleteError = new ArrayList<>(); 8 ArrayList<Integer> tableNumError = new ArrayList<>(); 9 ArrayList<Integer> timeError = new ArrayList<>(); 10 ArrayList<Integer> orderError = new ArrayList<>(); 11 Scanner input = new Scanner(System.in); 12 ArrayList<String> inputs = new ArrayList<>(); 13 14 String in = input.nextLine(); 15 while(!in.equals("end")) { 16 inputs.add(in); 17 in = input.nextLine(); 18 } 19 inputs.add(in); 20 ArrayList<Integer> desk = new ArrayList<>();//含table的下标 21 Menu menu = new Menu(); 22 ArrayList<Table> tables = new ArrayList<>();//桌子列表 23 while(!inputs.get(i).contains("table")) { 24 String[] dish = inputs.get(i).split(" ");//创建菜单 25 if(dish[1].matches("[1-9][\\d]{0,2}")){ 26 int price = Integer.parseInt(dish[1]); 27 if(price > 0&&price < 300) 28 menu.addDish(dish[0],price);//菜名和单价 29 else System.out.println(price+" price out of range"); 30 } 31 else System.out.println("wrong format"); 32 i++; 33 } 34 while(!inputs.get(i).contains("end")) { 35 36 if(inputs.get(i).contains("table")) { 37 38 if(inputs.get(i).matches("table\\s[1-9][\\d]*\\s[1-9][\\d]{3}/[\\d]{1,2}/[\\d]{1,2}\\s" 39 + "[\\d]{1,2}/[\\d]{1,2}/[\\d]{1,2}")) { 40 String[] tableInfo =inputs.get(i).split(" ");//创建桌子 41 int num = Integer.parseInt(tableInfo[1]); 42 if(num <= 55&&num >= 1) { 43 String[] date = tableInfo[2].split("/"); 44 String[] time = tableInfo[3].split("/"); 45 int[] Date = new int[date.length]; 46 int[] Time = new int[time.length]; 47 for(k = 0;k < date.length;k++) 48 Date[k] = Integer.parseInt(date[k]); 49 for(k = 0;k < time.length;k++) 50 Time[k] = Integer.parseInt(time[k]); 51 int[] mon_maxnum = {0,31,28,31,30,31,30,31,31,30,31,30,31}; 52 if(Date[0] == 2023 || Date[0] == 2022) { 53 if(Date[1] >= 1&&Date[1] <= 12) { 54 if(Date[2] <= mon_maxnum[Date[1]]) { 55 Table table = new Table(tableInfo[1],tableInfo[2],tableInfo[3]); 56 tables.add(table); 57 j++; 58 flag = 1; 59 dishNum = 0; 60 System.out.println("table "+num+":"); 61 } 62 else System.out.println(num+" date error"); 63 } 64 else System.out.println(num+" date error"); 65 } 66 else System.out.println("not a valid time period"); 67 } 68 else System.out.println(num+" table num out of range"); 69 } 70 else {System.out.println("wrong format"); 71 72 } 73 } 74 else if(flag == 1){ 75 if(inputs.get(i).contains("delete")) { 76 flag = 0; 77 String[] deletes = inputs.get(i).split(" "); 78 int num = Integer.parseInt(deletes[0]); 79 if(tables.get(j-1).getOrder().findRecordByNum(dishNum)){//找到该记录 80 tables.get(j-1).getOrder().delARecordByOrderNum(dishNum); 81 System.out.println("abc"); 82 flag1 = 1; 83 dishNum++; 84 } 85 else { 86 if(flag1 == 0){ 87 System.out.println(num+" delete error"); 88 } 89 else System.out.println("deduplication "); 90 } 91 } 92 else { 93 if(inputs.get(i).matches("[\\d]+\\s.+\\s[1-9]\\s[1-9][\\d]*")) {//格式正确 94 String[] dishInfo =inputs.get(i).split(" ");//存入一条点菜记录 95 int Num = Integer.parseInt(dishInfo[0]);//点菜序号 96 int portion = Integer.parseInt(dishInfo[2]);//份量 97 int number = Integer.parseInt(dishInfo[3]);//份数 98 if((portion == 1||portion == 2||portion == 3) 99 &&number >= 1&&number <= 15) { 100 if(menu.searthDish(dishInfo[1]) != -1) { 101 tables.get(j-1).getOrder().addARecord(Num, 102 menu.dishs.get(menu.searthDish(dishInfo[1])),portion,number);//添加一条菜品信息 103 // for(k = 0;k < tables.get(j-1).getOrder().records.size();k++) 104 System.out.println(tables.get(j-1).getOrder().records.get(a).orderNum//输出订单信息 105 +" "+tables.get(j-1).getOrder().records.get(a).d.name+" "+ 106 tables.get(j-1).getOrder().records.get(a).getPrice()); 107 a++; 108 } 109 else System.out.println(dishInfo[1]+" does not exist"); 110 } 111 else { 112 if(portion != 1&&portion != 2&&portion != 3) { 113 System.out.println(Num+" portion out of range "+portion); 114 } 115 else if(number < 1||number > 15) { 116 System.out.println(Num+" num out of range "+number); 117 } 118 } 119 } 120 else System.out.println("wrong format"); 121 122 // else if(dishInfo.length == 2||dishInfo.length == 3){ 123 // System.out.println("invalid dish"); 124 } 125 } 126 i++; 127 } 128 for(i = 0;i < tables.size();i++) 129 System.out.println("table "+tables.get(i).tableNum+": "+ 130 tables.get(i).getOrder().getTotalPrice()+" "+tables.get(i).getOrder().getTotalPrice()*0); 131 132 } 133 } 134 class Table{ 135 String tableNum;//桌子序号 136 String date; 137 String time; 138 Order order = new Order(); 139 140 public Table(){ 141 142 } 143 public Table(String tableNum,String date,String time){ 144 this.tableNum = tableNum; 145 this.date = date; 146 this.time = time; 147 } 148 Order getOrder() { 149 // order = new Order(); 150 return this.order; 151 } 152 // String[] dateInfo = date.split("/"); 153 // String[] timeInfo = time.split("/"); 154 // int num = Integer.parseInt(tableNum); 155 // int[] dInfo = new int[3]; 156 // int[] tInfo = new int[3]; 157 // for(i = 0;i < 3;i++){ 158 // dInfo[i] = Integer.parseInt(dateInfo[i]); 159 // tInfo[i] = Integer.parseInt(timeInfo[i]); 160 // } 161 } 162 class Dish{ 163 String name;//菜名 164 int unit_price = 0;//菜品单价 165 public Dish(){ 166 167 } 168 public Dish(String name,int unit_price){ 169 this.name = name; 170 this.unit_price = unit_price; 171 } 172 public String getName(){ 173 return name; 174 } 175 public void setName(String name){ 176 this.name = name; 177 } 178 public int getPrice(int portion){ 179 int price = 0; 180 if(portion == 1){ 181 price = (int)unit_price; 182 } 183 else if(portion == 2){ 184 price = (int)(1.5*unit_price); 185 } 186 else if(portion == 3){ 187 price = (int)(2*unit_price); 188 } 189 return price; 190 } 191 } 192 class Menu{ 193 ArrayList<Dish> dishs = new ArrayList<>(); 194 ArrayList<Dish> specialDishs = new ArrayList<>(); 195 public Menu(){ 196 197 } 198 int i = 0; 199 int searthDish(String dishName){ 200 for(i = 0;i < dishs.size();i++) 201 if((dishs.get(i).name).equals(dishName)){ 202 break; 203 } 204 if(i < dishs.size()) 205 return i; 206 else return -1; 207 } 208 void addDish(String dishName,int unit_price){ 209 210 Dish dish = new Dish(dishName,unit_price); 211 dishs.add(dish); 212 } 213 void addSpecialDish(String dishName,int unit_price){ 214 Dish dish = new Dish(dishName,unit_price); 215 specialDishs.add(dish); 216 } 217 } 218 class Record{ 219 int orderNum;//序号 220 Dish d;//菜品 221 int portion;//份额 222 int num;//份数 223 int flag = 0; 224 public Record(){ 225 226 } 227 public Record(int orderNum,Dish d,int portion,int num){ 228 this.orderNum = orderNum; 229 this.d = d; 230 this.portion = portion; 231 this.num = num; 232 } 233 int getPrice(){//计价,计算本条记录的价格 234 235 return d.getPrice(portion)*num; 236 } 237 public void showRecord() { 238 if(portion>=1&&portion<=3&&num>=1&&num<=15) { 239 System.out.println(orderNum+" "+d.name+" "+getPrice()); 240 flag = 0; 241 } 242 else { 243 if(portion<1||portion>3) 244 System.out.println(orderNum+" portion out of range "+portion); 245 if(num<1||num>15) 246 System.out.println(orderNum+" num out of range "+num); 247 flag = 1; 248 } 249 } 250 } 251 252 class Order { 253 int totalprice = 0; 254 int i = 0,k = 0,a= 0; 255 ArrayList<Record> records = new ArrayList<>(); 256 int getTotalPrice(){//计算订单的总价 257 for(i = 0;i < records.size();i++) { 258 a = records.get(i).getPrice(); 259 if(records.get(i).flag == 1) { 260 a = 0; 261 } 262 totalprice += a; 263 } 264 return totalprice; 265 266 } 267 void addARecord(int orderNum,Dish d,int portion,int num){ 268 // int ordernum = Integer.parseInt(orderNum); 269 // int por = Integer.parseInt(portion); 270 // int number = Integer.parseInt(num); 271 Record record = new Record(orderNum,d,portion,num); 272 records.add(record); 273 }//添加一条菜品信息到订单中。 274 275 void delARecordByOrderNum(int orderNum){ 276 records.remove(orderNum-1); 277 }//根据序号删除一条记录 278 279 boolean findRecordByNum(int orderNum){//根据序号查找一条记录 280 for(i = 0;i < records.size();i++) 281 if(records.get(i).orderNum == orderNum){ 282 break; 283 } 284 if(i == records.size()) { 285 return false; 286 } 287 else return true; 288 } 289 }
类图如下:

报表内容如下:


分析如下:
1.该题是第四次作业第一题的迭代,题目要求与之前差不多,但增加了更多异常情况,使得题目变得更加复杂。
2.根据类图可知,这几个类有很亲密的关联,此题的难点在于,如何将众多异常情况和正常情况与输出结果一一对应起来。
3.我的解题思路是先输入信息,不论格式是否合法合理。再将信息拆分开来,判断信息是否合法合理,最后根据合法的信息,输出对应的结果。
(3)踩坑心得
第四次作业
7-1 菜单计价程序-3

分析如下:
这次作业共有7道题目,本题是难度最大的一题。起初看到这题,我着实被题目吓到了,题目之长,让我望而生怯。我失去了做出
这道题目的信心,于是我转向了后面的题目。等我做完后六题后我发现同学们都没有做第一题,所以在我的心中对这题的恐惧感增加了,
我开始觉得大家都做不出来,那我也没必要做了。这就是我只得到一分的原因。
我以后会避免这种情况的发生,认真对待每一道题,拒绝摆烂,就算最后结果还是做不出来,我仍然会用尽全力完成它。
7-3 去掉重复的数据


分析如下:
由于这题在之前的题目集中出现过,所以我按照之前的方法,又写了一遍,结果总是会有运行超时的错误。
由于在题目中n的范围是1~100000,所以如果使用for循环,对每一个元素进行判断的话,将会非常缓慢,从而导致超时。
于是我去网上搜索老师提到过的哈希表及相关内容,在和同学讨论后得知应该使用LinkedHashset。最后改进代码如下:


第五次作业
7-5 日期问题面向对象设计(聚合一)

分析如下:
经过不断的修改,最终分数最终停在了48分,仅有一个测试点未通过。根据测试点提示,我得知是某一个日期超出范围,但没有
输出wrong format导致的。于是我回到了判断日期是否合理的checkInputValidity方法中。

仔细分析后发现我只是笼统的把日期小于31大于1当作合理日期,却忽略了有些月份没有31天,于是我试着输入了
3 2014 4 31 2020 6 14
结果是:

结果并没有输出wrong format。
发现问题后我开始修改,修改后的:



第六次作业
7-1 菜单计价程序-4

分析如下:
根据测试点提示可知,当桌号格式错误时未输出“wrong format”,于是我开始查看判定桌号信息是否符合格式的代码:

修改后:

修改前是先将桌子信息拆分开,再各自判定输入信息是否符合格式,修改后是先整体判定输入信息是否符合格式,
再将信息拆分开。这样就避免了不符合格式的信息被拆分开,导致的错误。

(4)改进建议:
第一次作业:
7-4 单词统计与排序

第二次作业:
7-5 日期问题面向对象设计(聚合一)
代码中使用了大量的switch语句,使得代码变得十分冗长,而且这些语句十分相似。应该寻找更加简便的方法,
例如可以将每月最大天数存入一个数组中,这样就可以判断天数和对应的数组元素的关系,便可实现日期的增减。


第三次作业
7-1 菜单计价程序-4
这道题目的主要改进方向是思路方向,在做这道题是没有一个准确的思路和和方向,都是做到哪想到哪,
所以常常要去修改之前的代码,导致作业进度十分缓慢。以后做题前应该先对题目有个大概的了解,在确定
方向后再着手写代码。
(5)总结
通过这三次的作业,我对java这门高级语言有了更加深入的了解。相较于之前的三次作业,这三次的作业难度直线上升,我也从中学到了
更多有用的知识。(1)学会了使用StringBuffer类,再作业四7-4这题中为了能够更加方便地删除字符串中的指定字符,我选择使用StringBuffer
类。(2)学会了使用ArrayList这个泛型,在第六次作业7-1这题中,由于不确定菜单和订单中菜品的数量,所以不好使用数组,所以我选择使用
ArrayList泛型。(3)对封装性有了更加深入的了解,在代码中大量使用了public和private来限制类的可见性。(4)学会了创建多个类,并且通过
对象的创建和方法的引用使各个类之间产生联系。除了学到很多知识外,我还认识到了自己的错误。对待作业的态度十分散漫,认为自己能够轻松
解决,甚至把别人不写当成自己不写的理由。总之,这次的作业做的不太满意,还有许多需要改进的地方。
 
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号