一、前言:
此次的BLOG-2是关于PTA的第四、五次大作业以及期中考试的题目分析。在PTA第四、五的两次大作业是在菜单三的基础上进行一个功能的增加。而期中考试主要是对知识点对点的测试。
PTA菜单四考察了很多错误输入情况,PTA菜单五则是在三的条件下去延伸了菜的一些特色。这两次的大作业和期中考试的四道题目主要考察了Java中类的结构构造,继承和多态(Java语言的三大
特性:封装、继承、多态),抽象类与接口,还有list接口的使用(尤其是ArrayList动态数组容器类),再就是对一些方法和Comparable等接口学习使用。
但是在这其中学习和使用最多并且尤为重要的,还是类的构建和使用。
这次的题量虽然只有六道,但是精而简,大作业的存在一定难度,需要学生付出大量的时间和精力,同时也有助于提高我们的的综合素质和技术水平,期中考试主要还是考察了对继承和多态的一
个简单的使用,并且考察了学生的接口学习。并且相对PTA的多次大作业而言,期中考试的难度是不如大作业的(并且相较上届的期中考试也是更简单的(看到了之前的期中考试的博客))。
二、设计与分析:
PTA菜单四(点击“菜单计价程序四-题目”,可见题目要求):
1 7-1 菜单计价程序-4 2 分数 100 3 作者 蔡轲 4 单位 南昌航空大学 5 本体大部分内容与菜单计价程序-3相同,增加的部分用加粗文字进行了标注。 6 7 设计点菜计价程序,根据输入的信息,计算并输出总价格。 8 9 输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。 10 11 菜单由一条或多条菜品记录组成,每条记录一行 12 13 每条菜品记录包含:菜名、基础价格 两个信息。 14 15 订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。 16 17 桌号标识独占一行,包含两个信息:桌号、时间。 18 19 桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。 20 21 点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。 22 23 不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。 24 25 删除记录格式:序号 delete 26 27 标识删除对应序号的那条点菜记录。 28 29 如果序号不对,输出"delete error" 30 31 代点菜信息包含:桌号 序号 菜品名称 份额 分数 32 33 代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。 34 35 程序最后按输入的桌号从小到大的顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。 36 37 每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。 38 39 折扣的计算方法(注:以下时间段均按闭区间计算): 40 41 周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。 42 43 周末全价,营业时间:9:30-21:30 44 45 如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours" 46 47 参考以下类的模板进行设计(本内容与计价程序之前相同,其他类根据需要自行定义): 48 49 菜品类:对应菜谱上一道菜的信息。 50 51 Dish { 52 53 String name;//菜品名称 54 55 int unit_price; //单价 56 57 int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) } 58 59 菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 60 61 Menu { 62 63 Dish[] dishs ;//菜品数组,保存所有菜品信息 64 65 Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 66 67 Dish addDish(String dishName,int unit_price)//添加一道菜品信息 68 69 } 70 71 点菜记录类:保存订单上的一道菜品记录 72 73 Record { 74 75 int orderNum;//序号 76 77 Dish d;//菜品\\ 78 79 int portion;//份额(1/2/3代表小/中/大份) 80 81 int getPrice()//计价,计算本条记录的价格 82 83 } 84 85 订单类:保存用户点的所有菜的信息。 86 87 Order { 88 89 Record[] records;//保存订单上每一道的记录 90 91 int getTotalPrice()//计算订单的总价 92 93 Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。 94 95 delARecordByOrderNum(int orderNum)//根据序号删除一条记录 96 97 findRecordByNum(int orderNum)//根据序号查找一条记录 98 99 } 100 101 本次课题比菜单计价系列-3增加的异常情况: 102 103 1、菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish" 104 105 2、桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error" 106 107 3、同一桌菜名、份额相同的点菜记录要合并成一条进行计算,否则可能会出现四舍五入的误差。 108 109 4、重复删除,重复的删除记录输出"deduplication :"+序号。 110 111 5、代点菜时,桌号不存在,输出"Table number :"+被点菜桌号+" does not exist";本次作业不考虑两桌记录时间不匹配的情况。 112 113 6、菜谱信息中出现重复的菜品名,以最后一条记录为准。 114 115 7、如果有重复的桌号信息,如果两条信息的时间不在同一时间段,(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)以内算统一时段),此时输出结果按不同的记录分别计价。 116 117 8、重复的桌号信息如果两条信息的时间在同一时间段,此时输出结果时合并点菜记录统一计价。前提:两个的桌号信息的时间都在有效时间段以内。计算每一桌总价要先合并符合本条件的饭桌的点菜记录,统一计价输出。 118 119 9、份额超出范围(1、2、3)输出:序号+" portion out of range "+份额,份额不能超过1位,否则为非法格式,参照第13条输出。 120 121 10、份数超出范围,每桌不超过15份,超出范围输出:序号+" num out of range "+份数。份数必须为数值,最高位不能为0,否则按非法格式参照第16条输出。 122 123 11、桌号超出范围[1,55]。输出:桌号 +" table num out of range",桌号必须为1位或多位数值,最高位不能为0,否则按非法格式参照第16条输出。 124 125 12、菜谱信息中菜价超出范围(区间(0,300)),输出:菜品名+" price out of range "+价格,菜价必须为数值,最高位不能为0,否则按非法格式参照第16条输出。 126 127 13、时间输入有效但超出范围[2022.1.1-2023.12.31],输出:"not a valid time period" 128 129 14、一条点菜记录中若格式正确,但数据出现问题,如:菜名不存在、份额超出范围、份数超出范围,按记录中从左到右的次序优先级由高到低,输出时只提示优先级最高的那个错误。 130 131 15、每桌的点菜记录的序号必须按从小到大的顺序排列(可以不连续,也可以不从1开始),未按序排列序号的输出:"record serial number sequence error"。当前记录忽略。(代点菜信息的序号除外) 132 133 16、所有记录其它非法格式输入,统一输出"wrong format" 134 135 17、如果记录以“table”开头,对应记录的格式或者数据不符合桌号的要求,那一桌下面定义的所有信息无论正确或错误均忽略,不做处理。如果记录不是以“table”开头,比如“tab le 55 2023/3/2 12/00/00”,该条记录认为是错误记录,后面所有的信息并入上一桌一起计算。 136 137 本次作业比菜单计价系列-3增加的功能: 138 139 菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+基础价格+"T" 140 141 例如:麻婆豆腐 9 T 142 143 菜价的计算方法: 144 145 周一至周五 7折, 周末全价。 146 147 注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价: 148 149 计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。 150 151 最后将所有记录的菜价累加得到整桌菜的价格。 152 153 输入格式: 154 桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS) 155 156 菜品记录格式: 157 158 菜名+英文空格+基础价格 159 160 如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。 161 162 点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。 163 164 删除记录格式:序号 +英文空格+delete 165 166 代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数 167 168 最后一条记录以“end”结束。 169 170 输出格式: 171 按输入顺序输出每一桌的订单记录处理信息,包括: 172 173 1、桌号,格式:table+英文空格+桌号+”:”+英文空格 174 175 2、按顺序输出当前这一桌每条订单记录的处理信息, 176 177 每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名 178 179 如果删除记录的序号不存在,则输出“delete error” 180 181 最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价 182 183 输入样例: 184 在这里给出一组输入。例如: 185 186 麻婆豆腐 12 187 油淋生菜 9 T 188 table 31 2023/2/1 14/20/00 189 1 麻婆豆腐 1 16 190 2 油淋生菜 1 2 191 2 delete 192 2 delete 193 end 194 输出样例: 195 在这里给出相应的输出。例如: 196 197 table 31: 198 1 num out of range 16 199 2 油淋生菜 18 200 deduplication 2 201 table 31: 0 0 202 输入样例1: 203 份数超出范围+份额超出范围。例如: 204 205 麻婆豆腐 12 206 油淋生菜 9 T 207 table 31 2023/2/1 14/20/00 208 1 麻婆豆腐 1 16 209 2 油淋生菜 4 2 210 end 211 输出样例1: 212 份数超出范围+份额超出范围。例如: 213 214 table 31: 215 1 num out of range 16 216 2 portion out of range 4 217 table 31: 0 0 218 输入样例2: 219 桌号信息错误。例如: 220 221 麻婆豆腐 12 222 油淋生菜 9 T 223 table a 2023/3/15 12/00/00 224 1 麻婆豆腐 1 1 225 2 油淋生菜 2 1 226 end 227 输出样例2: 228 在这里给出相应的输出。例如: 229 230 wrong format 231 输入样例3: 232 混合错误:桌号信息格式错误+混合的菜谱信息(菜谱信息忽略)。例如: 233 234 麻婆豆腐 12 235 油淋生菜 9 T 236 table 55 2023/3/31 12/000/00 237 麻辣香锅 15 238 1 麻婆豆腐 1 1 239 2 油淋生菜 2 1 240 end 241 输出样例3: 242 在这里给出相应的输出。例如: 243 244 wrong format 245 输入样例4: 246 错误的菜谱记录。例如: 247 248 麻婆豆腐 12.0 249 油淋生菜 9 T 250 table 55 2023/3/31 12/00/00 251 麻辣香锅 15 252 1 麻婆豆腐 1 1 253 2 油淋生菜 2 1 254 end 255 输出样例4: 256 在这里给出相应的输出。例如: 257 258 wrong format 259 table 55: 260 invalid dish 261 麻婆豆腐 does not exist 262 2 油淋生菜 14 263 table 55: 14 10 264 输入样例5: 265 桌号格式错误(以“table”开头)+订单格式错误(忽略)。例如: 266 267 麻婆豆腐 12 268 油淋生菜 9 T 269 table a 2023/3/15 12/00/00 270 1 麻婆 豆腐 1 1 271 2 油淋生菜 2 1 272 end 273 输出样例5: 274 在这里给出相应的输出。例如: 275 276 wrong format 277 输入样例6: 278 桌号格式错误,不以“table”开头。例如: 279 280 麻婆豆腐 12 281 油淋生菜 9 T 282 table 1 2023/3/15 12/00/00 283 1 麻婆豆腐 1 1 284 2 油淋生菜 2 1 285 tab le 2 2023/3/15 12/00/00 286 1 麻婆豆腐 1 1 287 2 油淋生菜 2 1 288 end 289 输出样例6: 290 在这里给出相应的输出。例如: 291 292 table 1: 293 1 麻婆豆腐 12 294 2 油淋生菜 14 295 wrong format 296 record serial number sequence error 297 record serial number sequence error 298 table 1: 26 17菜单计价程序四-题目
PTA菜单四得分代码(点击“菜单计价程序四-代码”,可见代码):
1 import java.util.Scanner; 2 import java.math.BigDecimal; 3 import java.time.LocalDate; 4 import java.time.LocalTime; 5 import java.util.Arrays; 6 import java.util.regex.Matcher; 7 import java.util.regex.Pattern; 8 9 public class Main { 10 11 public static void main(String[] args) { 12 Scanner scanner = new Scanner(System.in); 13 String message = null; 14 boolean isOrder = false; 15 Menu menu = new Menu(); 16 Order[] orders = new Order[1]; 17 String users = ""; 18 19 int i = -1; 20 while (true) { 21 message = scanner.nextLine(); 22 if ("end".equals(message)) { 23 break; 24 } 25 if (message.contains("delete")) { 26 String[] strings = message.split(" "); 27 orders[i].delARecordByOrderNum(Integer.parseInt(strings[0])); 28 continue; 29 } 30 if (message.contains("table")) { 31 i++; 32 isOrder = true; 33 if (i > 0) { 34 Order[] newOrders = Arrays.copyOf(orders, orders.length + 1); 35 orders = newOrders; 36 } 37 String[] strings = message.split(" "); 38 if (strings[3].length()>10) { 39 continue; 40 } 41 if (strings[4].length() != 11 || !(strings[4].substring(0,3).equals("180") || strings[4].substring(0,3).equals("181")||strings[4].substring(0,3).equals("189")||strings[4].substring(0,3).equals("133")||strings[4].substring(0,3).equals("135")||strings[4].substring(0,3).equals("136"))){ 42 continue; 43 } 44 orders[i] = new Order(); 45 46 47 // 48 orders[i].table = Integer.parseInt(strings[1]); 49 50 orders[i].name = strings[3]; 51 if (i == 0) { 52 users += strings[3]; 53 } else if (!users.contains(strings[3])) { 54 users = users + "," + strings[3]; 55 } 56 orders[i].phone = strings[4]; 57 orders[i].date = strings[5]; 58 orders[i].time = strings[6]; 59 continue; 60 } 61 62 if (isOrder) { 63 orders[i] = addRecord(message,menu,orders,i); 64 } else { 65 String[] strings = message.split(" "); 66 if (message.contains("T")) { 67 if (strings.length != 4) { 68 System.out.println("wrong format"); 69 continue; 70 } 71 menu.addDish(strings[0], strings[1], Integer.parseInt(strings[2]), strings[3]); 72 } else { 73 if (strings.length!=3) { 74 System.out.println("wrong format"); 75 continue; 76 } 77 menu.addDish(strings[0], Integer.parseInt(strings[1])); 78 } 79 } 80 } 81 String chuan; 82 String jin; 83 String zhe; 84 int chuanNum; 85 int jinNum; 86 int zheNum; 87 User use ; 88 for (String user : users.split(",")) { 89 use = new User(); 90 for (int j = 0; j < orders.length; j++) { 91 chuan = ""; 92 jin = ""; 93 zhe = ""; 94 chuanNum = 0; 95 jinNum = 0; 96 zheNum = 0; 97 if (user == null || user.length() == 0) { 98 return; 99 } 100 if (!user.equals(orders[j].name)) { 101 continue; 102 } 103 if (orders == null) { 104 return; 105 } 106 107 if (orders[j].records == null) { 108 continue; 109 } 110 int totalPrice = orders[j].getTotalPrice(); 111 String price = getPrice(use,orders[j].time, orders[j].date, totalPrice); 112 113 if (price.equals(" out of opening hours")) { 114 System.out.print("table " + orders[j].table +":" +price); 115 return; 116 } 117 System.out.println("table " + orders[j].table + ":"); 118 for (Record record : orders[j].records) { 119 String name = record.d.name; 120 if (record.d.taste != null) { 121 if (record.d.taste.equals("川菜")) { 122 chuan += "," + record.degree; 123 chuanNum += record.num; 124 } else if (record.d.taste.equals("晋菜")) { 125 jin += "," +record.degree; 126 jinNum += record.num; 127 } else if (record.d.taste.equals("浙菜")) { 128 zhe += "," + record.degree; 129 zheNum += record.num;; 130 } 131 } 132 for (Dish dish : menu.dishs) { 133 if (dish.name.equals(name)) { 134 record.d.unit_price = dish.unit_price; 135 } 136 } 137 System.out.println(record.orderNum + " " + record.d.name + " " + record.getPrice()); 138 } 139 140 System.out.print("table " + orders[j].table +":" + totalPrice + price); 141 taste(chuan,zhe,jin,chuanNum,zheNum,jinNum); 142 System.out.println(); 143 use.name = orders[i].name; 144 use.phone = orders[i].phone; 145 ; 146 147 } 148 if (use.name == null || use.name.length() == 0) { 149 continue; 150 } 151 System.out.println(use.name + " " + use.phone + " " + use.total ); 152 153 } 154 155 156 } 157 158 static void taste(String chuan, String zhe, String jin, int chuanNum, int zheNum, int jinNum) { 159 int sum = 0; 160 int j = 0; 161 if (chuan != null || chuan.length() != 0) { 162 j = 0; 163 String[] split = chuan.substring(1).split(","); 164 for (String s : split) { 165 j++; 166 sum += Integer.parseInt(s); 167 } 168 System.out.print(" 川菜 " + chuanNum+ " "); 169 int degree = sum / j; 170 if (degree == 0) { 171 System.out.print("不辣"); 172 }else if (degree ==1) { 173 System.out.print("微辣"); 174 } else if (degree ==2) { 175 System.out.print("稍辣"); 176 } else if (degree ==3) { 177 System.out.print("辣"); 178 } else if (degree == 4) { 179 System.out.print("很辣"); 180 } else if (degree == 5) { 181 System.out.print("爆辣"); 182 } 183 } 184 185 if (jin != null && jin.length() != 0) { 186 j = 0; 187 sum = 0; 188 String[] split = jin.substring(1).split(","); 189 for (String s : split) { 190 j++; 191 sum += Integer.parseInt(s); 192 } 193 System.out.print(" 晋菜 " + jinNum+ " "); 194 int degree = sum / j; 195 if (degree == 0) { 196 System.out.print("不酸"); 197 }else if (degree ==1) { 198 System.out.print("微酸"); 199 } else if (degree ==2) { 200 System.out.print("稍酸"); 201 } else if (degree ==3) { 202 System.out.print("酸"); 203 } else if (degree == 4) { 204 System.out.print("很酸"); 205 } 206 } 207 208 if (zhe != null && zhe.length() != 0) { 209 j = 0; 210 sum = 0; 211 String[] split = zhe.substring(1).split(","); 212 for (String s : split) { 213 j++; 214 sum += Integer.parseInt(s); 215 } 216 System.out.print(" 浙菜 " + zheNum+ " "); 217 int degree = sum / j; 218 if (degree == 0) { 219 System.out.print("不甜"); 220 }else if (degree ==1) { 221 System.out.print("微甜"); 222 } else if (degree ==2) { 223 System.out.print("稍甜"); 224 } else if (degree ==3) { 225 System.out.print("甜"); 226 } 227 } 228 } 229 230 public static Order addRecord(String message, Menu menu, Order[] orders, int i) { 231 String[] strings = message.split(" "); 232 if (isNumeric(strings[1])) { 233 Dish dish = menu.searchDish(strings[2]); 234 if (dish == null) { 235 System.out.println(strings[2] + "does not exist"); 236 return orders[i]; 237 } 238 int index = Integer.parseInt(strings[0]); 239 if (strings.length == 5) { 240 orders[index].addARecord(Integer.parseInt(strings[1]), dish, Integer.parseInt(strings[3]), Integer.parseInt(strings[4])); 241 System.out.println(strings[1] + " table " + (i + 1) + " pay for table " + index + " " + dish.getPrice(Integer.parseInt(strings[4]))); 242 return orders[i]; 243 } else { 244 if ("川菜".equals(dish.taste) && Integer.parseInt(strings[3]) > 5) { 245 System.out.println("spicy num out of range:" + strings[3]); 246 return orders[i]; 247 } else if("晋菜".equals(dish.taste) && Integer.parseInt(strings[3]) > 4) { 248 System.out.println("acidity num out of range:" + strings[3]); 249 return orders[i]; 250 }else if("浙菜".equals(dish.taste) && Integer.parseInt(strings[3]) > 3) { 251 System.out.println("sweetness num out of range:" + strings[3]); 252 return orders[i]; 253 } 254 orders[Integer.parseInt(strings[0])-1].addARecord(Integer.parseInt(strings[1]), dish, Integer.parseInt(strings[3]), Integer.parseInt(strings[4]), Integer.parseInt(strings[5])); 255 System.out.println(strings[1] + " table " + (i + 1) + " pay for table " + index + " " + Integer.parseInt(strings[5])*dish.getPrice(Integer.parseInt(strings[4]))); 256 } 257 258 } 259 Dish dish = menu.searchDish(strings[1]); 260 if (dish == null) { 261 // System.out.println(strings[1] + "does not exist"); 262 return orders[i]; 263 } 264 if ("T".equals(dish.characteristic)) { 265 if ("川菜".equals(dish.taste) && Integer.parseInt(strings[2]) > 5) { 266 System.out.println("spicy num out of range:" + strings[2]); 267 return orders[i]; 268 } else if("晋菜".equals(dish.taste) && Integer.parseInt(strings[2]) > 4) { 269 System.out.println("acidity num out of range:" + strings[2]); 270 return orders[i]; 271 }else if("浙菜".equals(dish.taste) && Integer.parseInt(strings[2]) > 3) { 272 System.out.println("sweetness num out of range:" + strings[2]); 273 return orders[i]; 274 } 275 orders[i].addARecord(Integer.parseInt(strings[0]), dish, Integer.parseInt(strings[2]), Integer.parseInt(strings[3]), Integer.parseInt(strings[4])); 276 } else { 277 orders[i].addARecord(Integer.parseInt(strings[0]), dish, Integer.parseInt(strings[2]), Integer.parseInt(strings[3])); 278 } 279 return orders[i]; 280 } 281 282 static boolean isNumeric(String str) { 283 Pattern pattern = Pattern.compile("[0-9]*"); 284 Matcher isNum = pattern.matcher(str); 285 if (!isNum.matches()) { 286 return false; 287 } 288 return true; 289 } 290 291 292 public static String getPrice(User use, String times, String dates, int price) { 293 String[] date = dates.split("/"); 294 String[] time = times.split("/"); 295 296 LocalDate nowDate = LocalDate.of(Integer.parseInt(date[0]), Integer.parseInt(date[1]), Integer.parseInt(date[2])); 297 LocalTime nowTime = LocalTime.of(Integer.parseInt(time[0]), Integer.parseInt(time[1]), Integer.parseInt(time[2])); 298 if (nowDate.getDayOfWeek().getValue() == 7 || nowDate.getDayOfWeek().getValue() == 6) { 299 LocalTime start = LocalTime.of(9, 30, 00); 300 LocalTime end = LocalTime.of(21, 30, 00); 301 if (nowTime.isAfter(start) && nowTime.isBefore(end)) { 302 use.total +=price; 303 return " " + price; 304 } else { 305 return " out of opening hours"; 306 } 307 308 } 309 310 LocalTime nigthStart = LocalTime.of(16, 59, 59); 311 LocalTime nigthEnd = LocalTime.of(20, 30, 1); 312 313 if (nowTime.isAfter(nigthStart) && nowTime.isBefore(nigthEnd)) { 314 BigDecimal bigDecimal = new BigDecimal(price * 0.7).setScale(0, BigDecimal.ROUND_HALF_UP); 315 use.total += bigDecimal.intValue(); 316 return " " + bigDecimal.intValue(); 317 } 318 LocalTime start = LocalTime.of(10, 29, 59); 319 LocalTime end = LocalTime.of(14, 30, 1); 320 if (nowTime.isAfter(start) && nowTime.isBefore(end)) { 321 BigDecimal bigDecimal = new BigDecimal(price * 0.7).setScale(0, BigDecimal.ROUND_HALF_UP); 322 price = bigDecimal.intValue(); 323 use.total += price; 324 return " " + price; 325 } 326 return " out of opening hours"; 327 } 328 } 329 330 class User{ 331 String name; 332 String phone; 333 int total; 334 } 335 336 class Dish { 337 338 String name;//菜品名称 339 340 String taste;// 特色类型 341 342 String characteristic; // 是否特色 343 344 int unit_price; //单价 345 346 int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) 347 { 348 if (portion == 1) { 349 return unit_price; 350 } else if (portion == 2) { 351 BigDecimal bigDecimal = new BigDecimal(unit_price * 1.5).setScale(0, BigDecimal.ROUND_HALF_UP); 352 int price = bigDecimal.intValue(); 353 return price; 354 } else if (portion == 3) { 355 return unit_price * 2; 356 } 357 return -1; 358 } 359 360 public Dish(String name, int unit_price) { 361 this.name = name; 362 this.unit_price = unit_price; 363 } 364 365 public Dish(String dishName) { 366 name = dishName; 367 } 368 369 public Dish(String name, String taste, String characteristic, int unit_price) { 370 this.name = name; 371 this.taste = taste; 372 this.characteristic = characteristic; 373 this.unit_price = unit_price; 374 } 375 } 376 377 class Menu { 378 379 Dish[] dishs ;//菜品数组,保存所有菜品信息 380 381 Dish searchDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 382 { 383 if (dishs == null) { 384 return null; 385 } 386 for (Dish dish : dishs) { 387 if (dishName.equals(dish.name)) { 388 return dish; 389 } 390 } 391 return null; 392 } 393 void addDish(String dishName,int unit_price)//添加一道菜品信息 394 { 395 Dish newDish = new Dish(dishName, unit_price); 396 int length = 0; 397 if (dishs != null) { 398 length = dishs.length; 399 } else { 400 length = 0; 401 } 402 Dish[] newDishs = new Dish[length + 1]; 403 for (int i = 0; i < length; i++) { 404 newDishs[i] = dishs[i]; 405 } 406 newDishs[length] = newDish; 407 dishs = newDishs; 408 } 409 410 void addDish(String dishName,String taste, int unit_price,String characteristic)//添加一道菜品信息 411 { 412 Dish newDish = new Dish(dishName,taste,characteristic,unit_price); 413 int length = 0; 414 if (dishs != null) { 415 length = dishs.length; 416 } else { 417 length = 0; 418 } 419 Dish[] newDishs = new Dish[length + 1]; 420 for (int i = 0; i < length; i++) { 421 newDishs[i] = dishs[i]; 422 } 423 newDishs[length] = newDish; 424 dishs = newDishs; 425 } 426 } 427 428 429 class Order { 430 int table; 431 String time; 432 String date; 433 String name; // 客户 434 String phone; // 电话 435 436 Record[] records;//保存订单上每一道的记录 437 438 int getTotalPrice()//计算订单的总价 439 { 440 int sum = 0; 441 for (Record record : records) { 442 sum += record.getPrice(); 443 } 444 return sum; 445 } 446 447 void addARecord(int orderNum, Dish dish, int degree,int portion, int num)//添加一条菜品信息到订单中。 448 { 449 Record record = new Record(orderNum, dish ,degree, portion, num); 450 Record[] newRecords = null; 451 if (this.records == null) { 452 newRecords = new Record[1]; 453 newRecords[0] = record; 454 } else { 455 newRecords = Arrays.copyOf(this.records, records.length + 1); 456 newRecords[records.length] = record; 457 } 458 records = newRecords; 459 } 460 461 void addARecord(int orderNum, Dish dish, int portion, int num)//添加一条菜品信息到订单中。 462 { 463 Record record = new Record(orderNum, dish, portion, num); 464 Record[] newRecords = null; 465 if (this.records == null) { 466 newRecords = new Record[1]; 467 newRecords[0] = record; 468 } else { 469 newRecords = Arrays.copyOf(this.records, records.length + 1); 470 newRecords[records.length] = record; 471 } 472 records = newRecords; 473 } 474 475 void delARecordByOrderNum(int orderNum)//根据序号删除一条记录 476 { 477 Record[] newRecord = new Record[records.length - 1]; 478 int j = 0; 479 for (int i = 0; i < records.length; i++) { 480 if (records[i].orderNum == orderNum) { 481 continue; 482 } else { 483 if (j == records.length - 1) { 484 System.out.println("delete error"); 485 return; 486 } 487 newRecord[j++] = records[i]; 488 } 489 } 490 records = newRecord; 491 } 492 493 Record findRecordByNum(int orderNum)//根据序号查找一条记录 494 { 495 for (Record record : records) { 496 if (record.orderNum == orderNum) { 497 return record; 498 } 499 } 500 return null; 501 } 502 } 503 class Record { 504 505 int orderNum;//序号\\ 506 507 Dish d;//菜品\\ 508 509 int portion;//份额(1/2/3代表小/中/大份)\\ 510 511 int num; 512 513 int degree;//度 514 515 int getPrice()//计价,计算本条记录的价格\\ 516 { 517 return d.getPrice(portion) * num; 518 } 519 520 public Record(int orderNum, Dish dish, int portion, int num) { 521 this.orderNum = orderNum; 522 this.d = dish; 523 this.portion = portion; 524 this.num = num; 525 } 526 527 public Record(int orderNum, Dish dish, int degree, int portion, int num) { 528 this.orderNum = orderNum; 529 this.d = dish; 530 this.portion = portion; 531 this.num = num; 532 this.degree = degree; 533 } 534 }菜单计价程序四-代码
分析:(在截止之后的分析)
本次作业需要设计的类包括以下:
Menu:菜单类,包含不同菜品的名称,价格等信息,还需要支持特色菜的添加和价格计算方法。
Order:点菜类,包含点菜记录和序号信息,还需要支持点菜记录的合并和订单总价的计算方法。
Table:餐桌类,包含桌号和订单信息,还需要支持订单的合并和餐桌总价的计算方法。
Parser:解析器类,用于解析输入字符串并生成Menu,Order,Table等对象,还需要支持对不合法输入的处理,以及对特殊情况的判断和处理。
最终的系统可以按照以下的流程进行处理:
-
读入输入字符串并进行初步的语法检查。
-
对于每条输入记录,使用解析器创建相应的Order对象,并按桌号将其归并到相应的Table对象中。
-
检查所有输入记录的序号是否按照从小到大的顺序排列,如果不是则输出错误提示。
-
对于每个Table对象,将其中所有的Order对象按照菜品名称进行合并,再计算整个订单的总价(包括菜品折扣和四舍五入等处理)。
-
检查所有输入记录是否符合规定的各种限制条件,如桌号范围、菜品名称、份数、份额等范围限制、日期格式等问题,如果出现不合法的情况则输出相应的错误提示信息,整个系统的错误处理优先级按照题目要求进行处理。
-
输出所有订单的详细信息和计算结果。
在实现上述系统时,我们需要设计并实现合适的类和方法,以及适当的异常处理机制和流程控制方法。同时,还需要考虑如何优化系统的效率和稳定性,以确保其能够处理日常生活中较复杂的点餐和账单计算任务。
并且其中的异常处理情况很多。这点有特别注意。
PTA菜单五(点击“菜单计价程序五-题目”,可见题目要求);
1 7-1 菜单计价程序-5 2 分数 100 3 作者 蔡轲 4 单位 南昌航空大学 5 本题在菜单计价程序-3的基础上增加了部分内容,增加的内容用加粗字体标识。 6 7 注意不是菜单计价程序-4,本题和菜单计价程序-4同属菜单计价程序-3的两个不同迭代分支。 8 9 10 设计点菜计价程序,根据输入的信息,计算并输出总价格。 11 12 13 14 输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。 15 16 17 18 菜单由一条或多条菜品记录组成,每条记录一行 19 20 21 22 每条菜品记录包含:菜名、基础价格 三个信息。 23 24 25 26 订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。 27 28 29 30 桌号标识独占一行,包含两个信息:桌号、时间。 31 32 33 34 桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。 35 36 37 38 点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。 39 40 41 42 不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。 43 44 45 46 删除记录格式:序号 delete 47 48 49 50 标识删除对应序号的那条点菜记录。 51 52 53 54 如果序号不对,输出"delete error" 55 56 57 58 代点菜信息包含:桌号 序号 菜品名称 口味度 份额 份数 59 60 61 62 代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。 63 64 65 66 程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。 67 68 69 70 每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。 71 72 73 74 折扣的计算方法(注:以下时间段均按闭区间计算): 75 76 77 78 周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。 79 80 81 82 周末全价,营业时间:9:30-21:30 83 84 85 86 如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours" 87 88 89 90 参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。 91 92 93 94 Dish { 95 96 97 98 String name;//菜品名称 99 100 101 102 int unit_price; //单价 103 104 105 106 int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) } 107 108 109 110 菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 111 112 113 114 Menu { 115 116 117 118 Dish[] dishs ;//菜品数组,保存所有菜品信息 119 120 121 122 Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 123 124 125 126 Dish addDish(String dishName,int unit_price)//添加一道菜品信息 127 128 129 130 } 131 132 133 134 点菜记录类:保存订单上的一道菜品记录 135 136 137 138 Record { 139 140 141 142 int orderNum;//序号\\ 143 144 145 146 Dish d;//菜品\\ 147 148 149 150 int portion;//份额(1/2/3代表小/中/大份)\\ 151 152 153 154 int getPrice()//计价,计算本条记录的价格\\ 155 156 157 158 } 159 160 161 162 订单类:保存用户点的所有菜的信息。 163 164 165 166 Order { 167 168 169 170 Record[] records;//保存订单上每一道的记录 171 172 173 174 int getTotalPrice()//计算订单的总价 175 176 177 178 Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。 179 180 181 182 delARecordByOrderNum(int orderNum)//根据序号删除一条记录 183 184 185 186 findRecordByNum(int orderNum)//根据序号查找一条记录 187 188 189 190 } 191 192 193 194 ### 输入格式: 195 196 197 198 桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS) 199 200 201 202 菜品记录格式: 203 204 205 206 菜名+英文空格+基础价格 207 208 209 210 如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。 211 212 213 214 点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。 215 216 217 218 删除记录格式:序号 +英文空格+delete 219 220 221 222 代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数 223 224 225 226 最后一条记录以“end”结束。 227 228 229 230 ### 输出格式: 231 232 233 234 按输入顺序输出每一桌的订单记录处理信息,包括: 235 236 237 238 1、桌号,格式:table+英文空格+桌号+”:” 239 240 241 242 2、按顺序输出当前这一桌每条订单记录的处理信息, 243 244 245 246 每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名 247 248 249 250 如果删除记录的序号不存在,则输出“delete error” 251 252 253 254 最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价 255 256 257 258 以上为菜单计价系列-3的题目要求,加粗的部分是有调整的内容。本次课题相比菜单计价系列-3新增要求如下: 259 260 261 262 1、菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+口味类型+英文空格+基础价格+"T" 263 264 例如:麻婆豆腐 川菜 9 T 265 266 菜价的计算方法: 267 268 周一至周五 7折, 周末全价。 269 270 特色菜的口味类型:川菜、晋菜、浙菜 271 272 川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣; 273 274 晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸; 275 276 浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜; 277 278 例如:麻婆豆腐 川菜 9 T 279 280 输入订单记录时如果是特色菜,添加口味度(辣/酸/甜度)值,格式为:序号+英文空格+菜名+英文空格+口味度值+英文空格+份额+英文空格+份数 281 282 例如:1 麻婆豆腐 4 1 9 283 284 单条信息在处理时,如果口味度超过正常范围,输出"spicy/acidity/sweetness num out of range : "+口味度值,spicy/acidity/sweetness(辣度/酸度/甜度)根据菜品类型择一输出,例如: 285 286 acidity num out of range : 5 287 288 输出一桌的信息时,按辣、酸、甜度的顺序依次输出本桌菜各种口味的口味度水平,如果没有某个类型的菜,对应的口味(辣/酸/甜)度不输出,只输出已点的菜的口味度。口味度水平由口味度平均值确定,口味度平均值只综合对应口味菜系的菜计算,不做所有菜的平均。比如,某桌菜点了3份川菜,辣度分别是1、3、5;还有4份晋菜,酸度分别是,1、1、2、2,辣度平均值为3、酸度平均值四舍五入为2,甜度没有,不输出。 289 290 一桌信息的输出格式:table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格+"川菜"+数量+辣度+英文空格+"晋菜"+数量+酸度+英文空格+"浙菜"+数量+甜度。 291 292 如果整桌菜没有特色菜,则只输出table的基本信息,格式如下: 293 294 table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格 295 296 例如:table 1: 60 36 川菜 2 爆辣 浙菜 1 微甜 297 298 计算口味度时要累计本桌各类菜系所有记录的口味度总和(每条记录的口味度乘以菜的份数),再除以对应菜系菜的总份数,最后四舍五入。 299 300 注:本题要考虑代点菜的情况,当前桌点的菜要加上被其他桌代点的菜综合计算口味度平均值。 301 302 303 304 305 306 2、考虑客户订多桌菜的情况,输入时桌号时,增加用户的信息: 307 308 格式:table+英文空格+桌号+英文空格+":"+英文空格+客户姓名+英文空格+手机号+日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS) 309 310 例如:table 1 : tom 13670008181 2023/5/1 21/30/00 311 312 约束条件:客户姓名不超过10个字符,手机号11位,前三位必须是180、181、189、133、135、136其中之一。 313 314 输出结果时,先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。不考虑各桌时间段的问题,同一个客户的所有table金额都要累加。 315 316 输出用户支付金额格式: 317 318 用户姓名+英文空格+手机号+英文空格+支付金额 319 320 321 322 323 324 注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价: 325 326 327 328 计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。 329 330 将所有记录的菜价累加得到整桌菜的价格。 331 332 输入格式: 333 桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS) 334 335 336 337 菜品记录格式: 338 339 340 341 菜名+口味类型+英文空格+基础价格 342 343 344 345 如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。 346 347 348 349 点菜记录格式:序号+英文空格+菜名+英文空格+辣/酸/甜度值+英文空格+份额+英文空格+份数 注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。辣/酸/甜度取值范围见题目中说明。 350 351 352 353 删除记录格式:序号 +英文空格+delete 354 355 356 357 代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称**+英文空格+辣/酸/甜度值+**英文空格+份额+英文空格+分数 358 359 360 361 最后一条记录以“end”结束。 362 363 输出格式: 364 按输入顺序输出每一桌的订单记录处理信息,包括: 365 366 367 368 1、桌号,格式:table+英文空格+桌号+“:”+英文空格 369 370 371 372 2、按顺序输出当前这一桌每条订单记录的处理信息, 373 374 375 376 每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名 377 378 379 380 如果删除记录的序号不存在,则输出“delete error” 381 382 383 384 之后按输入顺序一次输出每一桌所有菜品的价格(整数数值), 385 386 格式:table+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格 387 388 389 390 最后按拼音顺序输出每位客户(不考虑客户同名或拼音相同的情况)的支付金额,格式: 用户姓名+英文空格+手机号+英文空格+支付总金额,按输入顺序排列。 391 392 输入样例1: 393 桌号时间超出营业范围。例如: 394 395 麻婆豆腐 川菜 12 T 396 油淋生菜 9 397 麻辣鸡丝 10 398 table 1 : tom 13605054400 2023/5/1 21/30/00 399 1 麻婆豆腐 3 1 2 400 2 油淋生菜 2 1 401 3 麻婆豆腐 2 3 2 402 end 403 输出样例1: 404 在这里给出相应的输出。例如: 405 406 table 1 out of opening hours 407 输入样例2: 408 一种口味的菜品。例如: 409 410 麻婆豆腐 川菜 12 T 411 油淋生菜 9 412 麻辣鸡丝 10 413 table 1 : tom 13605054400 2023/5/1 20/30/00 414 1 麻婆豆腐 2 1 2 415 2 油淋生菜 2 1 416 3 麻婆豆腐 2 3 2 417 end 418 输出样例2: 419 在这里给出相应的输出。例如: 420 421 table 1: 422 1 麻婆豆腐 24 423 2 油淋生菜 14 424 3 麻婆豆腐 48 425 table 1: 86 62 川菜 4 稍辣 426 tom 13605054400 62 427 428 输入样例3: 429 辣度值超出范围。例如: 430 431 麻婆豆腐 川菜 12 T 432 油淋生菜 9 433 麻辣鸡丝 10 434 table 1 : tom 13605054400 2023/5/1 18/30/00 435 1 麻婆豆腐 6 1 2 436 2 油淋生菜 1 1 437 3 麻婆豆腐 5 3 2 438 end 439 输出样例3: 440 在这里给出相应的输出。例如: 441 442 table 1: 443 spicy num out of range :6 444 2 油淋生菜 9 445 3 麻婆豆腐 48 446 table 1: 57 41 川菜 2 爆辣 447 tom 13605054400 41 448 输入样例4: 449 同一用户对应多桌菜。例如: 450 451 麻婆豆腐 川菜 12 T 452 油淋生菜 9 453 麻辣鸡丝 10 454 table 1 : tom 13605054400 2023/5/1 18/30/00 455 1 麻婆豆腐 1 1 2 456 2 油淋生菜 1 1 457 3 麻婆豆腐 2 2 2 458 table 2 : tom 13605054400 2023/5/6 18/30/00 459 1 麻婆豆腐 2 1 2 460 2 麻辣鸡丝 2 2 461 3 麻婆豆腐 2 1 1 462 end 463 输出样例4: 464 在这里给出相应的输出。例如: 465 466 table 1: 467 1 麻婆豆腐 24 468 2 油淋生菜 9 469 3 麻婆豆腐 36 470 table 2: 471 1 麻婆豆腐 24 472 2 麻辣鸡丝 30 473 3 麻婆豆腐 12 474 table 1: 69 49 川菜 4 稍辣 475 table 2: 66 66 川菜 3 稍辣 476 tom 13605054400 115 477 输入样例5: 478 多用户多桌菜。例如: 479 480 东坡肉 浙菜 25 T 481 油淋生菜 9 482 蜜汁灌藕 浙菜 10 T 483 刀削面 晋菜 10 T 484 醋浇羊肉 晋菜 30 T 485 麻婆豆腐 川菜 12 T 486 麻辣鸡丝 川菜 15 T 487 table 1 : tom 13605054400 2023/5/6 12/30/00 488 1 醋浇羊肉 4 1 1 489 3 刀削面 1 1 3 490 2 东坡肉 3 2 1 491 4 麻辣鸡丝 2 1 1 492 table 2 : jerry 18100334566 2023/5/1 12/30/00 493 1 醋浇羊肉 1 1 2 494 3 麻婆豆腐 2 2 1 495 4 麻辣鸡丝 2 3 3 496 table 3 : jerry 18100334566 2023/5/1 12/30/00 497 1 醋浇羊肉 2 1 1 498 3 蜜汁灌藕 1 1 2 499 2 东坡肉 2 2 1 500 4 麻辣鸡丝 5 1 1 501 end 502 输出样例5: 503 在这里给出相应的输出。例如: 504 505 table 1: 506 1 醋浇羊肉 30 507 3 刀削面 30 508 2 东坡肉 38 509 4 麻辣鸡丝 15 510 table 2: 511 1 醋浇羊肉 60 512 3 麻婆豆腐 18 513 4 麻辣鸡丝 90 514 table 3: 515 1 醋浇羊肉 30 516 3 蜜汁灌藕 20 517 2 东坡肉 38 518 4 麻辣鸡丝 15 519 table 1: 113 113 川菜 1 稍辣 晋菜 4 稍酸 浙菜 1 甜 520 table 2: 168 118 川菜 4 稍辣 晋菜 2 微酸 521 table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜 522 jerry 18100334566 191 523 tom 13605054400 113 524 输入样例6: 525 多用户多桌菜含代点菜。例如: 526 527 东坡肉 浙菜 25 T 528 油淋生菜 9 529 蜜汁灌藕 浙菜 10 T 530 刀削面 晋菜 10 T 531 醋浇羊肉 晋菜 30 T 532 麻婆豆腐 川菜 12 T 533 麻辣鸡丝 川菜 15 T 534 table 1 : tom 13605054400 2023/5/6 12/30/00 535 1 醋浇羊肉 4 1 1 536 3 刀削面 1 1 3 537 2 东坡肉 3 2 1 538 4 麻辣鸡丝 2 1 1 539 table 2 : jerry 18100334566 2023/5/1 12/30/00 540 1 1 醋浇羊肉 0 1 2 541 3 麻婆豆腐 2 2 1 542 4 麻辣鸡丝 2 3 3 543 table 3 : lucy 18957348763 2023/5/1 12/30/00 544 1 醋浇羊肉 2 1 1 545 3 蜜汁灌藕 1 1 2 546 2 东坡肉 2 2 1 547 4 麻辣鸡丝 5 1 1 548 end 549 输出样例6: 550 在这里给出相应的输出。例如: 551 552 table 1: 553 1 醋浇羊肉 30 554 3 刀削面 30 555 2 东坡肉 38 556 4 麻辣鸡丝 15 557 table 2: 558 1 table 2 pay for table 1 60 559 3 麻婆豆腐 18 560 4 麻辣鸡丝 90 561 table 3: 562 1 醋浇羊肉 30 563 3 蜜汁灌藕 20 564 2 东坡肉 38 565 4 麻辣鸡丝 15 566 table 1: 113 113 川菜 1 稍辣 晋菜 6 微酸 浙菜 1 甜 567 table 2: 168 118 川菜 4 稍辣 568 table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜 569 jerry 18100334566 118 570 lucy 18957348763 73 571 tom 13605054400 113 572 输入样例7: 573 错误的菜品记录和桌号记录,用户丢弃。例如: 574 575 东坡肉 25 T 576 油淋生菜 9 577 table 1 : tom 136050540 2023/5/1 12/30/00 578 2 东坡肉 3 2 1 579 end 580 输出样例7: 581 在这里给出相应的输出。例如: 582 583 wrong format 584 wrong format菜单计价程序五-题目
PTA菜单五得分代码;
1 import java.util.Arrays; 2 import java.util.Calendar; 3 import java.util.Comparator; 4 import java.util.Scanner; 5 6 public class Main { 7 public static void main(String[] args) { 8 Scanner sc = new Scanner(System.in); 9 Menu mu = new Menu(); 10 Table[] tablemes = new Table[10]; 11 int j = 0;//菜单数 12 int l = 0;//订单数 13 int k = 0;//代点菜数 14 Dish tt; 15 //int sum = 0; 16 int cntTable = 0;//桌号 17 int count; 18 String[] temp; 19 int a1, a2, a3, a4, a5; 20 21 while (true) { 22 String st = sc.nextLine(); 23 temp = st.split(" "); 24 if (st.equals("end")) break; 25 count = temp.length; 26 if (count == 2) {//一个空格 27 //String[] temp1 = st.split(" "); 28 if (temp[1].equals("delete")) {//第二个为delete 29 a1 = Integer.parseInt(temp[0]); 30 tablemes[cntTable].odt.delARecordByOrderNum(a1); 31 } else {//菜单添加 32 a2 = Integer.parseInt(temp[1]); 33 mu.dishs[j] = mu.addDish(temp[0], "", a2); 34 j++; 35 } 36 //continue; 37 } else if (count == 4) {//三个空格 38 //String[] temp2 = st.split(" "); 39 40 if ("T".equals(temp[3])) { // 特色菜添加 41 a2 = Integer.parseInt(temp[2]); 42 mu.dishs[j] = mu.addDish(temp[0], temp[1], a2); 43 j++; 44 continue; 45 } 46 47 //增加订单的情况 48 a3 = Integer.parseInt(temp[0]); 49 a4 = Integer.parseInt(temp[2]); 50 a5 = Integer.parseInt(temp[3]); 51 Record record = tablemes[cntTable].odt.addARecord(a3, temp[1], a4, a5, -1); 52 tt = mu.searthDish(temp[1]); 53 if (tt != null) { 54 record.d = tt; 55 int a = record.getPrice(); 56 System.out.println(record.orderNum + " " + tt.name + " " + a); 57 } 58 l++; 59 //continue; 60 } else if (count == 5) { // 点特色菜 61 a1 = Integer.parseInt(temp[0]); 62 a3 = Integer.parseInt(temp[2]); // 口味 63 a4 = Integer.parseInt(temp[3]); 64 a5 = Integer.parseInt(temp[4]); 65 66 tt = mu.searthDish(temp[1]); 67 if (tt == null) { 68 continue; 69 } 70 71 if ("川菜".equals(tt.flavorType) && a3 > 5) { 72 System.out.println("spicy num out of range :" + a3); 73 continue; 74 } 75 76 if ("晋菜".equals(tt.flavorType) && a3 > 4) { 77 System.out.println("acidity num out of range :" + a3); 78 continue; 79 } 80 81 if ("浙菜".equals(tt.flavorType) && a3 > 3) { 82 System.out.println("sweetness num out of range :" + a3); 83 continue; 84 } 85 86 Record record = tablemes[cntTable].odt.addARecord(a1, temp[1], a4, a5, a3); 87 record.d = tt; 88 int a = record.getPrice(); 89 System.out.println(record.orderNum + " " + tt.name + " " + a); 90 91 } else if (count == 6) { // 代点菜 92 //String[] temp3 = st.split(" "); 93 int num = Integer.parseInt(temp[1]); 94 a1 = Integer.parseInt(temp[1]); 95 a2 = Integer.parseInt(temp[3]); // 口味 96 a3 = Integer.parseInt(temp[4]); 97 a4 = Integer.parseInt(temp[5]); 98 tt = mu.searthDish(temp[2]); 99 if (tt == null) { 100 continue; 101 } 102 103 Record record = tablemes[cntTable].odt.addARecord(a1, "", a3, a4, a2); 104 record.d.unit_price = tt.unit_price; 105 int b = record.getPrice(); 106 107 // 代点,但是不计算价格 108 tablemes[num].odt.addARecord(a1, temp[2], a3, a4, a2).d.flavorType = tt.flavorType; 109 System.out.println(temp[1] + " table " + tablemes[cntTable].tableNum + " pay for table " + temp[0] + " " + b); 110 // tablemes[cntTable].sum += b; 111 l++; 112 } else if (count == 7) { 113 if (temp[0].equals("table")) { // 桌号 114 cntTable++;//跳过0; 115 l = 0; 116 tablemes[cntTable] = new Table(); 117 //tablemes[cntTable].tableDtime = st; 118 119 String[] arr = new String[]{"180", "181", "189", "133", "135", "136"}; 120 121 if (temp[3].length() > 10 || temp[4].length() != 11) { 122 System.out.print("wrong format\n"); 123 return; 124 } 125 126 boolean find = false; 127 128 for (String s : arr) { 129 if (s.equals(s.substring(0, 3))) { 130 find = true; 131 break; 132 } 133 } 134 135 if (!find) { 136 System.out.print("wrong format\n"); 137 return; 138 } 139 140 tablemes[cntTable].AheadProcess(temp); 141 if (tablemes[cntTable].discount(-1) == -1) { 142 System.out.println("table " + tablemes[cntTable].tableNum + " out of opening hours"); 143 return; 144 } 145 146 System.out.println("table " + cntTable + ": "); 147 } 148 } else { 149 System.out.print("wrong format\n"); 150 } 151 //st = sc.nextLine(); 152 153 } 154 155 User[] users = new User[cntTable + 1]; 156 int ui = 0; 157 for (int i = 1; i < cntTable + 1; i++) { 158 int price = tablemes[i].Gettottalprice(); 159 if (price == -1) { 160 continue; 161 } 162 boolean find = false; 163 for (int ii = 0; ii < ui; ii++) { 164 if (users[ii].name.equals(tablemes[i].name)) { 165 users[ii].amount += price; 166 find = true; 167 break; 168 } 169 } 170 171 if (find) { 172 continue; 173 } 174 User user = new User(); 175 user.name = tablemes[i].name; 176 user.phone = tablemes[i].phone; 177 user.amount = price; 178 users[ui++] = user; 179 } 180 181 User[] tmp = new User[ui]; 182 for (int i = 0; i < ui; i++) { 183 tmp[i] = users[i]; 184 } 185 186 Arrays.sort(tmp, new Comparator<User>() { 187 @Override 188 public int compare(User o1, User o2) { 189 return o1.name.compareTo(o2.name); 190 } 191 }); 192 193 for (User user : tmp) { 194 System.out.printf("%s %s %d\n", user.name, user.phone, user.amount); 195 } 196 } 197 198 } 199 200 class Dish { 201 String name; // 菜品名称 202 int unit_price; // 单价 203 //int num; 204 String flavorType = ""; // 口味类型 205 206 int getPrice(int portion) { 207 int peic = 0; 208 if (portion == 1) { 209 peic = unit_price; 210 } else if (portion == 2) { 211 peic = Math.round((float) (unit_price * 1.5)); 212 } else if (portion == 3) { 213 peic = (unit_price * 2); 214 } 215 return peic;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) 216 } 217 } 218 219 class Menu { 220 Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息 221 int count = 0; 222 223 Dish searthDish(String dishName) { 224 Dish temd = null; 225 for (int i = count - 1; i >= 0; i--) { 226 if (dishName.equals(dishs[i].name)) { 227 temd = dishs[i]; 228 break; 229 } 230 } 231 if (temd == null) { 232 System.out.println(dishName + " does not exist"); 233 } 234 return temd; 235 }//根据菜名在菜谱中查找菜品信息,返回Dish对象。 236 237 Dish addDish(String dishName, String flavorType, int unit_price) { 238 Dish dh = new Dish(); 239 dh.name = dishName; 240 dh.flavorType = flavorType; 241 dh.unit_price = unit_price; 242 count++; 243 return dh; 244 }//添加一道菜品信息 245 } 246 247 class Record { 248 int orderNum;//序号\ 249 //int AntherOrderNum; 250 Dish d = new Dish();//菜品\ 251 int num = 0; 252 int portion;//份额(1/2/3代表小/中/大份)\ 253 254 int flavour; // 口味度 255 256 //int exist = 1; 257 int getPrice() { 258 return d.getPrice(portion) * num; 259 } // 计价,计算本条记录的价格\ 260 } 261 262 class Order { 263 Record[] records = new Record[10]; // 保存订单上每一道的记录 264 int count = 0; //订单数量 265 266 //int forcount = 0;//代点菜的数量 267 /*int getTotalPrice(){ 268 int sum=0; 269 for(int i=0;i<count;i++){ 270 if(records[i].exist==0) 271 continue; 272 sum=sum+records[i].getPrice(); 273 } 274 return sum; 275 }//计算订单的总价*/ 276 Record addARecord(int orderNum, String dishName, int portion, int num, int flavour) { 277 Record record = new Record(); 278 279 record.d.name = dishName; 280 record.orderNum = orderNum; 281 record.portion = portion; 282 record.num = num; 283 record.flavour = flavour; 284 285 records[count] = record; 286 count++; 287 return record; 288 } // 添加一条菜品信息到订单中。 289 290 /*Record TakeOdfor(int AnotherNUm,int orderNum,String dishName,int portion,int num){ 291 Record rd2 = new Record(); 292 rd2.d.name = dishName; 293 rd2.orderNum = orderNum; 294 rd2.portion = portion; 295 rd2.d.num = num; 296 rd2.AntherOrderNum = AnotherNUm; 297 //forcount++; 298 return rd2; 299 }*/ 300 void delARecordByOrderNum(int orderNum) { 301 Record[] tmp = new Record[10];//保存订单上每一道的记录 302 int index = -1; 303 int c = 0; 304 for (int i = 0; i < records.length; i++) { 305 if (records[i].orderNum == orderNum) { 306 index = i; 307 continue; 308 } 309 tmp[c++] = records[i]; 310 } 311 312 if (index == -1) { 313 System.out.print("delete error\n"); 314 } else { 315 records = tmp; 316 count = c; 317 } 318 } // 根据序号删除一条记录 319 320 } 321 322 class Table { 323 int tableNum; 324 int year, month, day, week, hh, mm, ss; 325 // boolean f = true; 326 Order odt = new Order(); 327 328 int sum = 0; // 一桌价格 329 int disSum = 0; // 折扣价格 330 331 String name; 332 String phone; 333 //Order odre = new Order(); 334 335 int Gettottalprice() { 336 337 int spicy = 0, acidity = 0, sweetness = 0; 338 int s = 0, an = 0, sn = 0; 339 340 String[] spicyArr = new String[]{"不辣", "微辣", "稍辣", "辣", "很辣", "爆辣"}; 341 String[] acidityArr = new String[]{"不酸", "微酸", "稍酸", "酸", "很酸"}; 342 String[] sweetnessArr = new String[]{"不甜", "微甜", "稍甜", "甜"}; 343 344 int allPrice = 0, nPrice = 0; 345 for (int i = 0; i < odt.count; i++) { 346 Record r = odt.records[i]; 347 switch (r.d.flavorType) { 348 case "川菜": 349 spicy += r.num * r.flavour; 350 s += r.num; 351 break; 352 case "晋菜": 353 acidity += r.num * r.flavour; 354 an += r.num; 355 break; 356 case "浙菜": 357 sweetness += r.num * r.flavour; 358 sn += r.num; 359 break; 360 } 361 362 allPrice += r.getPrice(); 363 nPrice += Math.round(r.getPrice() * discount(r.flavour)); 364 } 365 366 367 StringBuilder sb = new StringBuilder(); 368 sb.append(String.format("table %d: %d %d", tableNum, allPrice, nPrice)); 369 if (s > 0) { 370 int round = (int) Math.round(1.0 * spicy / s); 371 sb.append(String.format(" 川菜 %d %s", s, spicyArr[round])); 372 } 373 if (an > 0) { 374 int round = (int) Math.round(1.0 * acidity / an); 375 sb.append(String.format(" 晋菜 %d %s", an, acidityArr[round])); 376 } 377 if (sn > 0) { 378 int round = (int) Math.round(1.0 * sweetness / sn); 379 sb.append(String.format(" 浙菜 %d %s", sn, sweetnessArr[round])); 380 } 381 System.out.println(sb); 382 383 return nPrice; 384 } 385 386 void AheadProcess(String[] temp) { 387 tableNum = Integer.parseInt(temp[1]); 388 name = temp[3]; 389 phone = temp[4]; 390 391 processTime(temp[5], temp[6]); 392 //CheckAtime(); 393 } 394 395 396 void processTime(String ymd, String hms) {//处理时间 397 String[] temp1 = ymd.split("/"); 398 String[] temp2 = hms.split("/"); 399 400 year = Integer.parseInt(temp1[0]); 401 month = Integer.parseInt(temp1[1]); 402 day = Integer.parseInt(temp1[2]); 403 404 Calendar c = Calendar.getInstance(); 405 c.set(year, (month - 1), day); 406 week = c.get(Calendar.DAY_OF_WEEK); 407 if (week == 1) week = 7; 408 else week--; 409 hh = Integer.parseInt(temp2[0]); 410 mm = Integer.parseInt(temp2[1]); 411 ss = Integer.parseInt(temp2[2]); 412 } 413 414 double discount(int flavour) { 415 double discnt = -1; 416 if (week >= 1 && week <= 5) { 417 if (hh >= 17 && hh < 20) discnt = 0.8; 418 else if (hh == 20 && mm < 30) discnt = 0.8; 419 else if (hh == 20 && mm == 30 && ss == 0) discnt = 0.8; 420 else if (hh >= 11 && hh <= 13 || hh == 10 && mm >= 30) discnt = 0.6; 421 else if (hh == 14 && mm < 30) discnt = 0.6; 422 else if (hh == 14 && mm == 30 && ss == 0) discnt = 0.6; 423 } else { 424 if (hh >= 10 && hh <= 20) discnt = 1.0; 425 else if (hh == 9 && mm >= 30) discnt = 1.0; 426 else if (hh == 21 && mm < 30 || hh == 21 && mm == 30 && ss == 0) discnt = 1.0; 427 } 428 if (flavour >= 0) { 429 // 特色菜 430 if (discnt == 0.8 || discnt == 0.6) { 431 discnt = 0.7; 432 } 433 } 434 return discnt; 435 } 436 } 437 438 class User { 439 String name; 440 String phone; 441 int amount; 442 }
分析如上;
复杂度分析如上:
分析;
本题需要设计以下类:
-
Dish(菜品)类:属性包括菜名、菜系、基础价格,以及特色菜的辣度/酸度/甜度,并且需要提供计算特色菜价格的方法和计算口味度平均值的方法。
-
Order(订单)类:属性包括桌号、点餐时间、客户姓名、手机号等用户信息,以及所点菜品记录,需要提供计算订单原始总价和折扣后总价的方法。
-
Table(桌子)类:属性包括桌号、包含的订单记录列表,需要提供计算桌子原始总价和折扣后总价的方法,以及计算桌子口味度平均值的方法。
-
Customer(顾客)类:属性包括姓名、电话号码、所点订单列表,需要提供计算顾客总支付金额的方法。
-
Menu(菜单)类:属性包括所有菜品列表。
-
Restaurant(餐厅)类:属性包括所有桌子列表和所有顾客列表,需要提供计算餐厅所有顾客总支付金额的方法。
其中,需要注意的是口味度平均值的计算需要分别针对不同的菜系进行累加和计算,以保证计算准确性。同时也需要考虑桌子共享菜品的情况,即同一份菜可能在不同的订单中出现,需要在计算口味度平均值时综合计算。
- Menu Class (菜单类)
该类主要负责管理餐厅的菜单,包括菜品的增加、删除、修改,以及菜单的打印等操作。它需要维护一个包含所有菜品的列表,并提供根据菜品名称或其他关键字进行查询的功能。同时,Menu类还需要提供对特色菜的处理,包括输入特色菜的信息,计算特色菜的口味度和价格等。
- Dish Class (菜品类)
该类表示一道菜品,包含名称、价格、类型、口味等属性。Dish类应该被设计成抽象类,派生出不同类型的菜品类(如川菜、晋菜、浙菜),并提供不同类型菜品的计算折扣价和口味度的方法。此外,Dish类还需要处理输入的口味度信息,并计算各项菜品的平均口味度。
- Order Class (订单类)
该类表示一份订单,包含桌号、客户信息、菜品选择、数量和口味度等属性。它需要维护一个菜品列表,并提供计算订单价格、显示订单信息等功能。Order类需要与Menu和Dish类进行合适的交互,以获取菜品信息和计算价格。此外,Order类还需要处理代点菜的情况,并进行口味度的累计计算。
- Table Class (桌子类)
该类表示一张桌子,包含桌号、订单列表等属性。它需要提供添加/删除订单、计算整桌价格、输出一张桌子的信息等功能。Table类需要调用Order类的方法来管理订单,并调用Dish类的方法来计算价格和口味度。
- Customer Class (顾客类)
该类表示一个顾客信息,包含姓名、手机号等属性。它需要维护一个所点的所有菜品的订单列表,并提供计算顾客需要支付的金额的功能。此外,Customer类还需要处理一个客户订多桌菜的情况,并将所有table金额累加到一起。
- Main Class (主类)
该类包含程序的主要逻辑,调用Menu、Table和Customer类来进行订单管理和金额计算。Main类需要实现输入和输出数据的方法,包括录入菜单、订单、客户信息和桌号等,输出菜单、订单、桌号和客户信息以及所有客户需支付金额的信息。
菜单五对输入限制非常多,在有一个格式错误可能是一个换行或者是空格而引起的,所以在输入这个设置中,确保不会因为格式问题而无法通过测试点。
期中考试1题目;
1 7-1 测验1-圆类设计 2 分数 12 3 4 全屏浏览题目 5 6 切换布局 7 作者 段喜龙 8 单位 南昌航空大学 9 创建一个圆形类(Circle),私有属性为圆的半径,从控制台输入圆的半径,输出圆的面积 10 11 输入格式: 12 输入圆的半径,取值范围为(0,+∞),输入数据非法,则程序输出Wrong Format,注意:只考虑从控制台输入数值的情况 13 14 输出格式: 15 输出圆的面积(保留两位小数,可以使用String.format(“%.2f”,输出数值)控制精度) 16 17 输入样例: 18 在这里给出一组输入。例如: 19 20 2.35 21 输出样例: 22 在这里给出相应的输出。例如: 23 24 17.35题目
代码:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner scanner = new Scanner(System.in); 6 7 try { 8 double radius = scanner.nextDouble(); 9 if(radius <= 0){ 10 System.out.println("Wrong Format"); 11 } else { 12 Circle circle = new Circle(radius); 13 System.out.println(String.format("%.2f", circle.getArea())); 14 } 15 } catch (Exception e) { 16 System.out.println("Wrong Format"); 17 } 18 } 19 } 20 21 class Circle { 22 private double radius; 23 24 public Circle(double radius) { 25 this.radius = radius; 26 } 27 28 public double getArea() { 29 return Math.PI * Math.pow(radius, 2); 30 } 31 }
分析:
这道题比较简单,就不给出类图和复杂度分析图了。
属性:
private double radius:圆的半径,访问修饰符为私有类型,只能在类的内部访问
方法:
public Circle():无参构造方法,用于创建一个默认半径为0的圆形对象
public Circle(double radius):有参构造方法,用于创建一个指定半径的圆形对象
public double getRadius():获取圆的半径
public void setRadius(double radius):设置圆的半径,如果参数小于等于0,则抛出IllegalArgumentException异常,提示输入数据非法
public double getArea():计算圆的面积,返回一个double类型的值,保留两位小数
在main()方法中,通过Scanner类从控制台输入圆的半径,然后创建一个Circle对象,调用setRadius()方法设置圆的半径,若半径小于等于0则会抛出IllegalArgumentException异常,提示输入数据非法。如果设置成功,则调用getArea()方法计算圆的面积,并通过String.format()方法保留两位小数输出结果;如果设置失败,则捕获异常并输出异常信息。
、期中考试题目二:
1 7-2 测验2-类结构设计 2 分数 18 3 4 全屏浏览题目 5 6 切换布局 7 作者 段喜龙 8 单位 南昌航空大学 9 设计一个矩形类,其属性由矩形左上角坐标点(x1,y1)及右下角坐标点(x2,y2)组成,其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数),求得该矩形的面积。类设计如下图: 10 11 12 13 14 输入格式: 15 分别输入两个坐标点的坐标值x1,y1,x2,y2。 16 17 输出格式: 18 输出该矩形的面积值(保留两位小数)。 19 20 输入样例: 21 在这里给出一组输入。例如: 22 23 6 5.8 -7 8.9 24 输出样例: 25 在这里给出相应的输出。例如: 26 27 40.30题目
代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); double x1 = scanner.nextDouble(); double y1 = scanner.nextDouble(); double x2 = scanner.nextDouble(); double y2 = scanner.nextDouble(); Point topLeftPoint = new Point(x1, y1); Point lowerRightPoint = new Point(x2, y2); Rectangle rectangle = new Rectangle(topLeftPoint, lowerRightPoint); double area = rectangle.getArea(); System.out.printf("%.2f", area); } } class Point { private double x; private double y; public Point() { this.x = 0; this.y = 0; } public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } } class Rectangle { private Point topLeftPoint; private Point lowerRightPoint; public Rectangle() { topLeftPoint = new Point(); lowerRightPoint = new Point(); } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength() { return Math.abs(lowerRightPoint.getX() - topLeftPoint.getX()); } public double getHeight() { return Math.abs(lowerRightPoint.getY() - topLeftPoint.getY()); } public double getArea() { return getLength() * getHeight(); } }
分析:
设计一个矩形类,
其属性包括矩形左上角坐标点(x1,y1)
右下角坐标点(x2,y2)
其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数)。该类需要定义一个计算矩形面积的方法。
在初始化时,传入矩形左上角坐标点和右下角坐标点,然后定义一个计算矩形面积的方法area();
该方法返回矩形的面积,通过计算矩形对角线上两点的距离得到。
这道题和第一题一样,其实十分简洁并且很好做,所以也就不再多说废话。
期中考试题目3:
1 将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类,类图如下所示: 2 3 4 5 6 试编程完成如上类图设计,主方法源码如下(可直接拷贝使用): 7 8 public static void main(String[] args) { 9 // TODO Auto-generated method stub 10 Scanner input = new Scanner(System.in); 11 12 int choice = input.nextInt(); 13 14 switch(choice) { 15 case 1://Circle 16 double radiums = input.nextDouble(); 17 Shape circle = new Circle(radiums); 18 printArea(circle); 19 break; 20 case 2://Rectangle 21 double x1 = input.nextDouble(); 22 double y1 = input.nextDouble(); 23 double x2 = input.nextDouble(); 24 double y2 = input.nextDouble(); 25 26 Point leftTopPoint = new Point(x1,y1); 27 Point lowerRightPoint = new Point(x2,y2); 28 29 Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint); 30 31 printArea(rectangle); 32 break; 33 } 34 35 } 36 其中,printArea(Shape shape)方法为定义在Main类中的静态方法,体现程序设计的多态性。 37 38 输入格式: 39 输入类型选择(1或2,不考虑无效输入) 40 对应图形的参数(圆或矩形) 41 42 输出格式: 43 图形的面积(保留两位小数) 44 45 输入样例1: 46 1 47 5.6 48 输出样例1: 49 在这里给出相应的输出。例如: 50 51 98.52 52 输入样例2: 53 2 54 5.6 55 -32.5 56 9.4 57 -5.6 58 输出样例2: 59 在这里给出相应的输出。例如: 60 61 102.22题目
代码:
import java.util.Scanner; abstract class Shape { public Shape() {} public abstract double getArea(); } class Circle extends Shape { private double radius = 0; public Circle() {} public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } } class Rectangle extends Shape { private Point topLeftPoint; private Point lowerRightPoint; public Rectangle() { topLeftPoint = new Point(); lowerRightPoint = new Point(); } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength() { return Math.abs(lowerRightPoint.getX() - topLeftPoint.getX()); } public double getHeight() { return Math.abs(lowerRightPoint.getY() - topLeftPoint.getY()); } @Override public double getArea() { return getLength() * getHeight(); } } class Point { private double x; private double y; public Point() {} public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } } public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int choice = input.nextInt(); switch(choice) { case 1://Circle double radius = input.nextDouble(); if(radius>0){ Shape circle = new Circle(radius); printArea(circle); } else System.out.println("Wrong Format"); break; case 2://Rectangle double x1 = input.nextDouble(); double y1 = input.nextDouble(); double x2 = input.nextDouble(); double y2 = input.nextDouble(); Point leftTopPoint = new Point(x1,y1); Point lowerRightPoint = new Point(x2,y2); Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint); printArea(rectangle); break; } } public static void printArea(Shape shape) { System.out.println(String.format("%.2f", shape.getArea())); } }
复杂度分析:
分析:
这道题在题目中已经给出了类图,因此我们在此给出复杂度分析图即可。
我们需要将这两个类合并设计,并抽象出一个 Shape 父类。因为圆形和矩形都是形状,所以我们可以将它们的共同属性和方法抽象到 Shape 类中。
Shape 类是一个抽象类,它包含一个抽象方法 getArea(),用于计算形状的面积。Circle 类和 Rectangle 类继承自 Shape 类,分别重写了 getArea() 方法,用于计算圆和矩形的面积。
我们从控制台输入圆的半径和矩形的坐标,分别创建了 Circle 和 Rectangle 的对象,并通过调用 getArea() 方法计算了它们的面积。最后,使用 String.format() 方法将结果保留两位小数并输出。
这题主要是继承这一方面,并在这道题中,他是有一个对错误输入的测试点,在首次提交的时候没注意,后来在“
case 1://Circle double radius = input.nextDouble(); if(radius>0){ Shape circle = new Circle(radius); printArea(circle); } else System.out.println("Wrong Format"); break;
”
这个case这里加了一个if的选择,通过了测试点。
期中考试题目4;
1 7-4 测验4-抽象类与接口 2 有题解 3 分数 40 4 5 全屏浏览题目 6 7 切换布局 8 作者 段喜龙 9 单位 南昌航空大学 10 在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。 11 提示:题目中Shape类要实现Comparable接口。 12 13 其中,Main类源码如下(可直接拷贝使用): 14 15 public class Main { 16 public static void main(String\[\] args) { 17 // TODO Auto-generated method stub 18 Scanner input = new Scanner(System.in); 19 ArrayList<Shape> list = new ArrayList<>(); 20 21 int choice = input.nextInt(); 22 23 while(choice != 0) { 24 switch(choice) { 25 case 1://Circle 26 double radiums = input.nextDouble(); 27 Shape circle = new Circle(radiums); 28 list.add(circle); 29 break; 30 case 2://Rectangle 31 double x1 = input.nextDouble(); 32 double y1 = input.nextDouble(); 33 double x2 = input.nextDouble(); 34 double y2 = input.nextDouble(); 35 Point leftTopPoint = new Point(x1,y1); 36 Point lowerRightPoint = new Point(x2,y2); 37 Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint); 38 list.add(rectangle); 39 break; 40 } 41 choice = input.nextInt(); 42 } 43 44 list.sort(Comparator.naturalOrder());//正向排序 45 46 for(int i = 0; i < list.size(); i++) { 47 System.out.print(String.format("%.2f", list.get(i).getArea()) + " "); 48 } 49 } 50 } 51 52 输入格式: 53 输入图形类型(1:圆形;2:矩形;0:结束输入) 54 55 输入图形所需参数 56 57 输出格式: 58 按升序排序输出列表中各图形的面积(保留两位小数),各图形面积之间用空格分隔。 59 60 输入样例: 61 在这里给出一组输入。例如: 62 63 1 64 2.3 65 2 66 3.2 67 3 68 6 69 5 70 1 71 2.3 72 0 73 输出样例: 74 在这里给出相应的输出。例如: 75 76 5.60 16.62 16.62题目
代码:
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; abstract class Shape implements Comparable<Shape> { public Shape() {} public abstract double getArea(); @Override public int compareTo(Shape other) { if (this.getArea() < other.getArea()) { return -1; } else if (this.getArea() > other.getArea()) { return 1; } else { return 0; } } } class Circle extends Shape { private double radius = 0; public Circle() {} public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } } class Rectangle extends Shape { private Point topLeftPoint; private Point lowerRightPoint; public Rectangle() { topLeftPoint = new Point(); lowerRightPoint = new Point(); } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength() { return Math.abs(lowerRightPoint.getX() - topLeftPoint.getX()); } public double getHeight() { return Math.abs(lowerRightPoint.getY() - topLeftPoint.getY()); } @Override public double getArea() { return getLength() * getHeight(); } } class Point { private double x; private double y; public Point() {} public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } } public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); ArrayList<Shape> list = new ArrayList<>(); int choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://Circle double radius = input.nextDouble(); if(radius>0) { Shape circle = new Circle(radius); list.add(circle); } else System.out.println("Wrong Format"); break; case 2://Rectangle double x1 = input.nextDouble(); double y1 = input.nextDouble(); double x2 = input.nextDouble(); double y2 = input.nextDouble(); Point leftTopPoint = new Point(x1,y1); Point lowerRightPoint = new Point(x2,y2); Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint); list.add(rectangle); break; } choice = input.nextInt(); } list.sort(Comparator.naturalOrder());//正向排序 for(int i = 0; i < list.size(); i++) { System.out.print(String.format("%.2f", list.get(i).getArea()) + " "); } } }
类图:
复杂度分析图;
分析:
- Circle 类 (圆形类)
Circle 类应该包含一个私有属性 radius 表示圆的半径,以及计算圆面积的方法。在控制台输入圆的半径后,调用计算面积的方法,将结果输出到控制台。如果输入数据非法,输出 "Wrong Format"。
- Rectangle 类 (矩形类)
Rectangle 类应该包含四个私有属性表示左上角坐标点和右下角坐标点的 x 和 y 坐标值。在控制台输入这四个坐标值后,调用计算面积的方法,将结果输出到控制台。
- Shape 类 (图形类)
Shape 类是 Circle 和 Rectangle 类的父类,它包含一个抽象方法 area(),代表计算图形面积的方法,并实现了 Comparable 接口,用于按照图形面积进行排序。由于 area() 方法是一个抽象方法,所以 Shape 类也是一个抽象类。
- Main 类 (主类)
Main 类的职责是从控制台读取数据,根据输入的形状类型分别创建 Circle 和 Rectangle 对象,并计算输出它们的面积。此外,它还需要将所有图形放入一个列表中,调用 Collections.sort() 方法按照面积大小进行排序,最后输出排序过后的图形信息。
综上所述,我们需要设计的类包括 Circle、Rectangle、Shape和 Main 四个类,分别实现圆形、矩形、图形抽象类和主要逻辑。其中 Shape 类是一个抽象类,Circle 和 Rectangle 类都是 Shape 类的具体子类。Main 类负责整合四个类的功能,进行数据输入输出和图形排序。
在其中我用“
abstract·class·Shape·implements·Comparable<Shape>·{
····public·Shape()·{}
····public·abstract·double·getArea();
····@Override
····public·int·compareTo(Shape·other)·{
········if·(this.getArea()·<·other.getArea())·{
············return·-1;
········}·else·if·(this.getArea()·>·other.getArea())·{
············return·1;
········}·else·{
············return·0;
········}
····}
}
”
来进行一个面积的排序。其他的方面我个人觉得和第三题没有很大差异。
三、踩坑心得:
PTA菜单四,五;
在菜单四和五中,我们需要对用户输入进行异常处理。在处理用户输入时,我们需要考虑到输入类型不匹配、输入数据超出范围等问题。因此,我们需要使用Java中的异常处理机制来处理这些问题。具体来说,我们可以使用try-catch语句来捕获异常,并给出相应的提示信息。
在菜单四和五中,我们对于不同的菜品需要有不同的计价方式。因此,我们可以使用继承与多态来实现这一功能。具体来说,我们可以定义一个菜品类作为父类,然后定义不同的子类来表示不同的菜品。在计价时,我们可以通过多态来调用不同的计价方法。
在菜单四和五中,我们需要使用List来存储菜品信息。List是Java中的一个容器接口,它可以存储一组有序的元素。在使用List时,我们需要注意其实现类的选择,比如ArrayList和LinkedList等。同时,我们还需要注意List的使用方法,比如添加元素、删除元素、修改元素和遍历元素等。
在菜单计价程序四和五中,我们还使用了一些Java方法来处理字符串、日期等数据类型。我们需要仔细阅读Java文档,理解这些方法的功能和使用方法。另外,我们还需要注意方法的返回值类型和异常处理,以确保代码的健壮性和可靠性。
期中考试:
在创建圆形类时,需要注意输入数据的范围,并且需要进行数据类型的转换。在计算圆的面积时,需要使用数学公式进行计算,并使用String.format()方法保留小数位数。在创建矩形类时,需要注意左上角和右下角坐标点的顺序,以及面积计算公式的正确性。在抽象出Shape父类,并实现Comparable接口时,需要考虑到排序的实现方式,可以使用Collections.sort()方法进行排序。同时,在设计类时,需要考虑到良好的封装性和代码的可读性。
并且在这两个当中都需要注意精度表示,尤其是在菜单的两个题目和期中考试计算中,他有特别要求四舍五入的这些要求。
四、主要困难以及改进建议:
、PTA第四,五次菜单;
主要困难:
1.异常处理方面,可能存在多种异常情况需要处理,如输入格式错误等,需要进行详细的异常处理,否则程序会崩溃。
2.继承与多态方面,需要对继承、多态等概念进行深入理解,并且需要考虑如何在程序中实现适当的继承和多态,以避免代码重复和冗余。
3.list中的容器接口方面,需要学习list的基本使用方法,并适当地使用容器接口,以便在程序中实现高效的数据存储和管理。
4.对程序中的输入格式有严格要求,需要输入正确的格式,否则程序会出错或者崩溃,需要进行严格的输入检查和处理。
改进建议:
1.在异常处理方面,可以在代码编写阶段即考虑可能出现的异常情况,并进行相应的异常处理,以避免程序出现异常。
2.在继承与多态方面,可以使用抽象类和接口等方式实现适当的继承和多态,以避免代码重复和冗余。
3.在list中的容器接口方面,可以使用ArrayList等高效的容器,并结合泛型等方式,实现更加简洁、高效的数据存储和管理。
4.在输入格式方面,可以使用正则表达式等方式对输入进行严格检查,以确保输入格式正确,从而避免程序出错或者崩溃。
、期中考试:
主要困难:
圆形类需要从控制台输入半径,需要进行输入格式的检查和异常处理;
输出圆的面积需要保留两位小数,可以使用String.format()方法控制精度;
矩形类需要根据左上角和右下角点的坐标计算矩形面积;
设计一个抽象的Shape父类,让Circle和Rectangle作为其子类,需要实现Comparable接口实现排序。
改进建议:
对于输入格式的检查和异常处理,可以使用try-catch语句来实现异常捕捉和处理;
输出圆的面积可以使用String.format()方法,也可以使用BigDecimal类来实现精确计算;
矩形类可以设计一个计算面积的方法,方便调用;
在Shape父类中可以定义一个抽象方法,让子类去实现,这样可以避免代码的重复性;
实现Comparable接口时,需要重写compareTo()方法,根据面积大小来进行排序。
五、总结:
在6-9周的Java学习中,我们学习了继承和多态的使用,这是面向对象编程的重要概念之一。我们学会了如何使用extends关键字来实现继承,以及如何使用super关键字来调用父类的构造方法。同时,我们也了解了多态的概念和使用方法,即同一种对象可以有多种不同的形态,可以通过向上转型和向下转型实现。
接下来我们学习了接口和抽象类的使用,这是Java中另一个重要的特性。接口是一种定义方法的契约,可以让不同的类实现相同的方法,从而实现代码的复用。抽象类则是一种不能被实例化的类,可以包含抽象方法和具体方法,可以作为其他类的父类被继承。
我们还学习了list接口容器以及泛型的使用,这是Java中常用的数据结构和类型安全的重要概念。我们了解了不同的list容器类型,如ArrayList和LinkedList,并学会了如何使用泛型来避免类型转换和类型错误。
在这段时间中,我们也学习了一些新的Java方法,如equals()、toString()、hashCode()等,这些方法可以方便我们对对象进行比较、输出和哈希处理。
最后,我们重点学习了类的构建和关系,这是Java编程中的基础。我们学会了如何定义类以及如何使用构造方法、静态变量和方法等。同时,我们也了解了不同类之间的关系,如继承、实现、组合和聚合等。
需要改进的地方可能是课程的深度和难度,有时候可能会感觉有些内容过于简单或者过于复杂。建议老师可以根据学生的反馈来适当调整课程难度和进度,让学生能够更好地掌握知识。同时也希望老师能够多提供一些实际应用的案例,让学生能够更好地理解Java编程的实际应用场景。
路漫漫其修远兮。
标签:String,int,double,BLOG,学院,table,软件,public,out From: https://www.cnblogs.com/yhttcoudx-1/p/17410640.html