一、前言
开头废话:
最后一次题目集,可以说是这段日子里对Java学习的总结,在这几个题目集中的没有很多关于算法的考察,而是更加强调其中代码设计,无论是菜单,还是成绩统计的迭代,也都不难看出代码设计的重要性,好的设计,符合面向对象的设计可在代码迭代中省时省力。之前的菜单还没怎么体会(因为我的完成度不高),但是在成绩统计中真的是深有体会,类的设计做好的话,一次迭代只需要改几个小时后提交就可以获得大量测试点通过后的感觉还是很爽,但要是没设计好,迭代一次也真的是跑断腿,随着新功能的加入,基本每个地方都需要修改就很头疼。
题目集分析:
OOP训练集07:
一道菜单迭代题(菜单-5),也是菜单的最后一次迭代,这次菜单题是在菜单3的基础上迭代,不是菜单4的迭代,菜单5没有菜单4那么多异常情况,而是加入口味度,口味度这个功能要求是很多的,比如口味度平均值的计算,对于我来说难度确实不小。
OOP训练集08:
一道成绩统计题(成绩统计-1),是新的系列,也是成绩统计的第一版本,其实总体跟菜单差不多,但是这一次其实更加注重类的设计,强调要用继承,相比于之前迭代的菜单,其实设计也不算复杂,难度还行
OOP训练集09:
一道统计关键词题,这次题目集属于额外内容,主要要求我们必须使用set,map和正则表达式进行Java中关键词出现次数统计,而且老师强调需要代码大小有要求,且必须使用面向对象设计,一方面要考虑测试点通过,另一方面要对代码结构进行精简,如果想尝试代码精简很多的话难度确实也不小。
OOP训练集10:
一道成绩统计迭代题(成绩统计-2),还有三道其他题目(考察HashMap和多态)难度可以说是送分的,成绩统计的第一次迭代加入了实验课的统计功能,增加的功能其实也不算多,难度不高。
OOP训练集11:
一道成绩统计迭代题(成绩统计-3),还有四道其他题目(考察排序,自定义接口和覆盖)也可以说是送分题,成绩统计的第二次迭代修改了课程计算总成绩的方式(分项成绩的权重计算总成绩),且要求修改类设计结构,将原本的继承改为组合,修改的地方比较多,难度较高。
二、设计与分析
菜单计价程序-5:
源代码
import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalTime; import java.time.temporal.ChronoField; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { @SuppressWarnings("resource") Scanner in = new Scanner(System.in); Dish[] dish = new Dish[10]; ArrayList<String> customs = new ArrayList<String>(); String[] command = in.nextLine().split(" "); for(int i = 0; !command[0].equals("table"); i++) { if(command.length > 2) { if(command.length == 4) { if(command[3].equals("T")) { dish[i] = new Dish(command[0],Integer.parseInt(command[2]),true); dish[i].setTaste(command[1]); } } else { System.out.println("wrong format"); dish[i] = new Dish(); } } else dish[i] = new Dish(command[0],Integer.parseInt(command[1]),false); if(!(dish[i].getUtilPrice() >= 0&&dish[i].getUtilPrice() < 300)) { System.out.println(dish[i].getName()+" price out of range "+dish[i].getUtilPrice()); dish[i] = new Dish(); } command = in.nextLine().split(" "); } Menu menu = new Menu(dish); if(command[0].equals("table")) { Custom[] custom = new Custom[10]; int customNum = 0; Table[] table = new Table[10]; int tableNum = 0; for(tableNum = 0; command[0].equals("table"); tableNum++) { custom[customNum] = new Custom(command[3],command[4]); table[tableNum] = new Table(Integer.parseInt(command[1]),command[3],custom[customNum].getPhone(),command[5],command[6]); if(!custom[customNum].getPhone().equals("error")&&custom[customNum].getName().length() <= 10) { if(table[tableNum].isOpeningHours()) { System.out.println("table "+table[tableNum].getNum()+": "); if(!customs.contains(custom[customNum].getName())) customs.add(custom[customNum].getName()); } } else System.out.println("wrong format"); Record[] records = new Record[10]; command = in.nextLine().split(" "); for(int j = 0; !(command[1].equals("delete")||command[0].equals("table")); j++) { if(table[tableNum].getPhone().equals("error")) { command = in.nextLine().split(" "); if(command[0].equals("end")) break; continue; } if(command[0].length() > 2) { if(command.length > 3) records[j] = new Record(1,new Dish(),0,0,0); else System.out.println("invalid dish"); } else { if(menu.searthDish(command[1]).getName().equals("notexist")) { System.out.println(command[1]+" does not exist"); records[j] = new Record(); } else { if(command.length > 4)//特色菜 records[j] = new Record(Integer.parseInt(command[0]),menu.searthDish(command[1]),Integer.parseInt(command[2]),Integer.parseInt(command[3]),Integer.parseInt(command[4])); else//非特色菜 records[j] = new Record(Integer.parseInt(command[0]),menu.searthDish(command[1]),0,Integer.parseInt(command[2]),Integer.parseInt(command[3])); } } command = in.nextLine().split(" "); if(command[0].equals("end")) break; } Order order = new Order(records,menu); table[tableNum].setOrder(order); if(!table[tableNum].getPhone().equals("error")&&table[tableNum].isOpeningHours()) order.showOrder(); if(!command[0].equals("end")) { while(command[1].equals("delete")) { order.delARecordByOrderNum(Integer.parseInt(command[0])); command = in.nextLine().split(" "); if(command[0].equals("end")) break; } } } for(int i = 0; i < tableNum; i++) { if(!table[i].getPhone().equals("error")) table[i].showTotal(); } Collections.sort(customs, new Comparator<String>(){ public int compare(String o1, String o2) { return o1.compareToIgnoreCase(o2); } } ); for(int i = 0; i < customs.size(); i++) { int total = 0; String phone = ""; for(int j = 0; j < tableNum; j++) { if(table[j].getName().equals(customs.get(i))&&!table[j].getPhone().equals("error")) { total += table[j].getDiscountedPrice(); phone = table[j].getPhone(); } } System.out.println(customs.get(i)+" "+phone+" "+total); } } else System.out.println("wrong format"); } } class Dish{ private String name; private int util_price; private boolean t; private String taste; public Dish() { name = ""; util_price = 0; t = false; } public Dish(String name,int util_price,boolean t){ this.name = name; this.util_price = util_price; this.t = t; } public String getName() { return name; } public int getUtilPrice() { return util_price; } public boolean getT() { return t; } public String getTaste() { return taste; } public void setTaste(String taste) { this.taste = taste; } public int getPrice(int portion){ double price = 0; switch(portion){ case 1:{ price = util_price; break; } case 2:{ price = util_price * 1.5; break; } case 3:{ price = util_price * 2; break; } } if(price - (int)price >= 0.5) return (int)price + 1; else return (int)price; } } class Menu{ private Dish[] dishs; public Menu(Dish[] dishs) { this.dishs = new Dish[dishs.length]; for(int i = 0; i < dishs.length; i++) { if(dishs[i] == null) this.dishs[i] = new Dish(); else this.dishs[i] = dishs[i]; } } public Dish searthDish(String dishName) { int num = 0; Dish flag = new Dish("notexist",0,false); for(int i = 0; i < dishs.length; i++) { if(dishs[i].getName().equals(dishName)) { num = i; flag = new Dish("exist",0,false); } } if(flag.getName().equals("exist")) return dishs[num]; else return flag; } public Dish addDish(String dishName,int unit_price,boolean t) { return new Dish(dishName,unit_price,t); } } class Record{ private int orderNum; private Dish d; private int taste;//口味度 private int portion; private int num; public Record() { orderNum = 0; d = new Dish(); taste = 0; portion = 0; num = 0; } public Record(int orderNum,Dish d,int taste,int portion,int num) { this.orderNum = orderNum; this.d = d; this.taste = taste; this.portion = portion; this.num = num; } public int getOrderNum(){ return orderNum; } public Dish getDish() { return d; } public int getPortion() { return portion; } public int getNum() { return num; } public int getTaste() { return taste; } public void setTaste(int taste) { this.taste = taste; } public int getPrice() { if(isTaste(taste,d).equals("yes")) { if(!d.getT()&&(portion < 0||portion > 3)) return 0; else if(d.getT()&&(portion < 0||portion > 3)) return 0; else { if(num > 15) return 0; else return d.getPrice(portion)*num; } } else return 0; } public String isTaste(int taste,Dish d) { if(d.getT()) { if(d.getTaste().equals("川菜")) { if(taste >= 0&&taste <= 5) return "yes"; else return "spicy"; } else if(d.getTaste().equals("晋菜")) { if(taste >= 0&&taste <= 4) return "yes"; else return "acidity"; } else if(d.getTaste().equals("浙菜")) { if(taste >= 0&&taste <= 4) return "yes"; else return "sweetness"; } else return "yes"; } else return "yes"; } public void Priceshow() { if(portion < 10) { if(!d.getT()&&(portion < 0||portion > 3)) System.out.println(orderNum+" num out of range "+portion); else if(d.getT()&&(portion < 0||portion > 3)) System.out.println(orderNum+" portion out of range "+portion); else if(!isTaste(taste,d).equals("yes")) { System.out.println(isTaste(taste,d)+" num out of range :"+taste); taste = 0; num = 0; } else { if(num > 15) System.out.println(orderNum+" num out of range "+num); else System.out.println(orderNum+" "+d.getName()+" "+getPrice()); } } else System.out.println("wrong format"); } } class Order{ private Record[] records; private Menu menu; private int[] taste = new int[3]; private int[] tasteNum = new int[3]; public Order(Record[] records,Menu menu) { this.records = new Record[records.length]; for(int i = 0; i < records.length; i++) if(records[i] == null) this.records[i] = new Record(); else this.records[i] = records[i]; this.menu = menu; for(int i = 0; i < 3; i++) { taste[i] = 0; tasteNum[i] = 0; } } public Record[] getRecords() { return records; } public int[] getTaste() { return taste; } public void setTaste(int[] taste) { this.taste = taste; } public int[] getTasteNum() { return tasteNum; } public void setTasteNum(int[] tasteNum) { this.tasteNum = tasteNum; } public int getTotalPrice() { int TotalPrice = 0; for(int i = 0; i < records.length; i++) { TotalPrice += records[i].getPrice(); } return TotalPrice; } public Record addARecord(int orderNum,String dishName,int portion,int num) { Dish d = menu.searthDish(dishName); Record error = new Record(); if(d.getName().equals("")) return error; else return new Record(orderNum,d,0,portion,num); } public void delARecordByOrderNum(int orderNum) { int flag = findRecordByNum(orderNum); if(flag != -1) { if(records[flag].getNum() == 0) System.out.println("deduplication "+ orderNum); records[flag] = new Record(orderNum,new Dish(),0,0,0); } else System.out.println("delete error"); } public int findRecordByNum(int orderNum) { for(int i = 0; i < records.length; i++) { if(records[i].getOrderNum() == orderNum) { return i; } } return -1; } public void averageTaste() { double[] totalTaste = new double[3]; for(int i = 0; i < 3; i++) { totalTaste[i] = 0; } for(int i = 0; i < records.length; i++ ) { if(records[i].getDish().getT()) { if(records[i].getDish().getTaste().equals("川菜")) { totalTaste[0] += records[i].getTaste()*records[i].getNum(); tasteNum[0] += records[i].getNum(); } else if(records[i].getDish().getTaste().equals("晋菜")) { totalTaste[1] += records[i].getTaste()*records[i].getNum(); tasteNum[1] += records[i].getNum(); } else if(records[i].getDish().getTaste().equals("浙菜")) { totalTaste[2] += records[i].getTaste()*records[i].getNum(); tasteNum[2] += records[i].getNum(); } } } for(int i = 0; i < 3; i++) { totalTaste[i] = totalTaste[i] / tasteNum[i]; if(totalTaste[i] - (int)totalTaste[i] >= 0.5) taste[i] = (int)totalTaste[i] + 1; else taste[i] = (int)totalTaste[i]; } } public void showOrder() {//展示每条记录的价格 for(int i = 0; i < records.length; i++) { if(records[i].getNum() != 0) { // int m = i; // for(m = i; m > 0; m--) { // if(records[m-1].getOrderNum() >= records[i].getOrderNum()) { // System.out.println("record serial number sequence error"); // records[i] = new Record(); // break; // } // } // if(m == 0) records[i].Priceshow(); } else { if(records[i].getOrderNum() == 1) System.out.println("wrong format"); } } } } class Table { private int num; private Order order; private String name; private String phone; private LocalDate date; private LocalTime time; private double total; public Table(int num, String name, String phone, String date, String time) { this.num = num; this.name = name; this.phone = phone; if(check(date)) { String[] DATE = date.split("/"); this.date = LocalDate.of(Integer.parseInt(DATE[0]),Integer.parseInt(DATE[1]),Integer.parseInt(DATE[2])); } else this.date = LocalDate.of(1,1,1); String[] TIME = time.split("/"); this.time = LocalTime.of(Integer.parseInt(TIME[0]),Integer.parseInt(TIME[1]),Integer.parseInt(TIME[2])); this.total = 0.0; } public void setOrder(Order order) { this.order = order; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public int getNum() { return num; } public Order getOrder() { return order; } public LocalDate getDate() { return date; } public LocalTime getTime() { return time; } public double getTotal() { return total; } public int getWeek() { return date.get(ChronoField.DAY_OF_WEEK); } public boolean isOpeningHours() { int week = getWeek(); if(week <= 5) { if(time.isAfter(LocalTime.of(16,59,59))&&time.isBefore(LocalTime.of(20,30,1))) return true; else if(time.isAfter(LocalTime.of(10,29,59))&&time.isBefore(LocalTime.of(14,30,1))) return true; else return false; } else { if(time.isAfter(LocalTime.of(9,29,59))&&time.isBefore(LocalTime.of(21,30,1))) return true; else return false; } } public int OpeningHours(int week,LocalTime time,boolean T) { if(week <= 5) { if(T) { return 7; } else { if(time.isAfter(LocalTime.of(16,59,59))&&time.isBefore(LocalTime.of(20,30,1))) return 8; else if(time.isAfter(LocalTime.of(10,29,59))&&time.isBefore(LocalTime.of(14,30,1))) return 6; else return -1; } } else { if(time.isAfter(LocalTime.of(9,29,59))&&time.isBefore(LocalTime.of(21,30,1))) return 10; else return -1; } } public int getDiscountedPrice() { int discountedPrice = 0; Record[] records = order.getRecords(); double[] price = new double[records.length]; for(int i = 0; i < records.length; i++) { price[i] = records[i].getPrice()*OpeningHours(getWeek(),getTime(),records[i].getDish().getT())*0.1; if(price[i] - (int)price[i] >= 0.5) price[i] = (int)price[i] + 1; else price[i] = (int)price[i]; } for(int i = 0; i < price.length; i++) discountedPrice += (int)price[i]; return discountedPrice; } public void showTaste() { order.averageTaste(); if(order.getTasteNum()[0] > 0) {//辣度 System.out.print(" 川菜 "); switch(order.getTaste()[0]) { case 0: System.out.print(order.getTasteNum()[0]+" 不辣"); break; case 1: System.out.print(order.getTasteNum()[0]+" 微辣"); break; case 2: System.out.print(order.getTasteNum()[0]+" 稍辣"); break; case 3: System.out.print(order.getTasteNum()[0]+" 辣"); break; case 4: System.out.print(order.getTasteNum()[0]+" 很辣"); break; case 5: System.out.print(order.getTasteNum()[0]+" 爆辣"); break; } } if(order.getTasteNum()[1] > 0) {//辣度 System.out.print(" 晋菜 "); switch(order.getTaste()[1]) { case 0: System.out.print(order.getTasteNum()[1]+" 不酸"); break; case 1: System.out.print(order.getTasteNum()[1]+" 微酸"); break; case 2: System.out.print(order.getTasteNum()[1]+" 稍酸"); break; case 3: System.out.print(order.getTasteNum()[1]+" 酸"); break; case 4: System.out.print(order.getTasteNum()[1]+" 很酸"); break; } } if(order.getTasteNum()[2] > 0) {//辣度 System.out.print(" 浙菜 "); switch(order.getTaste()[2]) { case 0: System.out.print(order.getTasteNum()[2]+" 不甜"); break; case 1: System.out.print(order.getTasteNum()[2]+" 微甜"); break; case 2: System.out.print(order.getTasteNum()[2]+" 稍甜"); break; case 3: System.out.print(order.getTasteNum()[2]+" 甜"); break; } } } public void showTotal() { int judge = OpeningHours(getWeek(),getTime(),false); if(judge == -1) System.out.println("table"+" "+num+" out of opening hours"); else { if(date.isAfter(LocalDate.of(2020,1,1))&&date.isBefore(LocalDate.of(2023,12,31))) { System.out.print("table"+" "+num+": "+order.getTotalPrice()+" "+getDiscountedPrice()); showTaste(); System.out.println(); } else System.out.println("not a valid time period"); } } public static boolean check (String str) { SimpleDateFormat sd = new SimpleDateFormat("yyyy/MM/dd"); try { sd.setLenient(false); sd.parse(str); } catch (Exception e) { return false; } return true; } } class Custom{ private String name; private String phone; private int consumption; public Custom() { name = ""; phone = ""; consumption = 0; } public Custom(String name, String phone) { super(); this.name = name; String regExp = "^(180|181|189|133|135|136)([0-9]{8}?)$"; Pattern pattern = Pattern.compile(regExp); Matcher matcher = pattern.matcher(phone); if(matcher.find()) this.phone = phone; else this.phone = "error"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public int getConsumption() { return consumption; } public void setConsumption(int consumption) { this.consumption = consumption; } }
类图

OOP训练集08:
OOP训练集09:
OOP训练集10:
OOP训练集11:
三、踩坑心得
四、改进建议
五、总结