前言:
本次Blog作业中囊括的题目集题量都不是很大,但其中不乏一些很有难度的题目,比如菜单计价系列,主要考察了正则表达式的书写使用以及异常捕获(try-catch)。期中考试的编程题则主要考察多态与继承等概念,测试点并不难。接下来是对以上题目的分析与总结
题目集4:
7-1 菜单计价程序-3:
相比于菜单-2,本题目主要增加了代点菜以及根据时间计算折扣的功能。如果你有将“桌”抽象成一个类的话代点菜功能只需要根据被点菜的桌号找到对应的桌对象,后面的计价就跟普通的点菜没有什么区别了。关于计算折扣的功能我推荐使用LocalDateTime库记录日期、时间和获取星期,比Calendar库好用、功能更多而且没有Bug
代码如下:
import java.util.ArrayList; import java.util.Scanner; import java.util.Vector; import java.util.regex.Pattern; public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); // Law law=new Law(); Menu menu=new Menu(); Order order=new Order(); String s; s=input.nextLine(); int tnum=0; while (!s.equals("end")) { String[] part=s.split(" "); if("delete".equals(part[1]))//delete { int n = Integer.parseInt(part[0]); int flag = 0; for (int i = 0; i < order.tables.get(tnum - 1).records.size(); i++) { if (order.tables.get(tnum - 1).records.get(i).number == n) { flag = 1; order.tables.get(tnum - 1).records.get(i).exist = 0; } } if (flag == 0) System.out.print("delete error;\n"); } else if("table".equals(part[0])) { tnum = Integer.parseInt(part[1]); Table table = new Table(); table.setTable(s); if (order.serchTable(table.tablenum) == -1) { order.tables.add(table); System.out.print("table " + tnum + ": \n"); } } else if(part.length==2)//写菜单 { if(menu.searthDish(part[0])==null) { Dish dish=new Dish(); dish.name=part[0]; dish.unit_price=Integer.parseInt(part[1]); menu.dishes.add(dish);//菜单添加菜品信息 } else { menu.searthDish(part[0]).setdish(part[0], Integer.parseInt(part[1])); } } else if(part.length==4)//给自己写订单 { if(menu.searthDish(part[1])==null) { System.out.print(part[1]+" does not exist\n"); } else{ Dish dish=new Dish(); int num=Integer.parseInt(part[3]); dish.name=part[1]; dish.unit_price = menu.searthDish(dish.name).unit_price; order.tables.get(tnum-1).addARecord(Integer.parseInt(part[0]), dish, Integer.parseInt(part[2]), num); System.out.print(part[0] + " " + part[1] + " " + dish.getPrice(Integer.parseInt(part[2])) * num + "\n"); } } else if(part.length==5)//给别桌写订单 { if(menu.searthDish(part[2])==null) { System.out.print(part[2]+" does not exist\n"); } else { Dish dish=new Dish(); int num=Integer.parseInt(part[4]); dish.name=part[2]; dish.unit_price = menu.searthDish(dish.name).unit_price; order.tables.get(tnum-1).addARecord(Integer.parseInt(part[1]), dish, Integer.parseInt(part[3]), num); System.out.print(part[1] + " table " + tnum + " pay for table "+part[0]+" "+ dish.getPrice(Integer.parseInt(part[3])) * num + "\n"); } } s=input.nextLine(); } order.showTable(); } } class Dish { String name;//菜品名称 int unit_price; //单价 int getPrice(int portion) { if (portion == 2) return (int) Math.round(1.5*unit_price) ; else if (portion == 3) return 2 * unit_price; else return unit_price; } void setdish(String name,int unit_price) { this.name=name; this.unit_price=unit_price; } } class Menu { ArrayList<Dish> dishes=new ArrayList<>();//菜品数组,保存所有菜品信息 Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 { for (Dish dish : dishes) { if (dishName.equals(dish.name)) return dish; } return null; } } class Record { int number;//序号 Dish d;//菜品 int portion;//份额(1/2/3代表小/中/大份) int num;//份数 int price;//单菜总价 int exist=1;//表示此订单是否已被删除 public Record(int number,Dish dish, int portion,int num) { this.number=number; this.d = dish; this.portion = portion; this.num = num; this.price = this.d.getPrice(portion) * this.num; } } class Order { public ArrayList<Table> tables=new ArrayList<>(); int serchTable(int n) { for (int i=0;i<tables.size();i++) { if(tables.get(i).tablenum==n) return i; } return -1; } void showTable() { for (Table table : tables) { if (table.open) System.out.print("table " + table.tablenum + ": " + Math.round(table.getSum()) + "\n"); else System.out.print("table " + table.tablenum + " out of opening hours\n"); } } } class Table { boolean open=true; int tablenum; public ArrayList<Record> records=new ArrayList<>();//保存订单上每一道的记录 public double sum=0; float discount=1; void addARecord(int number,Dish dish, int portion,int num) { Record record = new Record(number,dish, portion,num); records.add(record); } double getSum() { for (Record record : records) { if (record.exist == 1) sum =sum+ (record.price) * discount; } return sum; } void setTable(String s) { String[] part; part=s.split(" "); String[] part2; part2=part[2].split("/"); tablenum=Integer.parseInt(part[1]); int year=Integer.parseInt(part2[0])%100, month=Integer.parseInt(part2[1]), day=Integer.parseInt(part2[2]); if(month==1||month==2){ month=month+12; year=year-1; } part2=part[3].split("/"); int hour=Integer.parseInt(part2[0]), minute=Integer.parseInt(part2[1]); int day_of_week=(int)(year*1.2325+2.6*month+1.6+day)%7; if(day_of_week>5||day_of_week==0){ if((hour>9&&hour<21)||(hour==9&&minute>=30)||(hour==21&&minute<=30)) { discount = 1; return; } } else { if(((hour>=17&&hour<20)||(hour==20&&minute<=30))) { discount = 0.8F; return; } if(((hour>10&&hour<14)||(hour==10&&minute>=30)||(hour==14&&minute<=30))) { discount = 0.6F; return; } } open=false; } }
7-2 单词统计与排序:
将输入字符串使用split分割后去除重复单词再排序即可
代码如下:
import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Vector; // Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`, // then press Enter. You can now see whitespace characters in your code. public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); Vector<String> str=new Vector<>(); String[] ss=new String[]{}; String s=new String(),temp=new String(); s=input.nextLine(); ss=s.split("\\,|\\ |\\."); for(int i=0;i<ss.length;i++) { if(ss[i].equals("")) continue; int flag=0; for(int j=i+1;j<ss.length;j++) { if(ss[i].equals(ss[j])) flag=1; } if(flag==0) str.add(ss[i]); } for(int i=0;i<str.size();i++) { for(int j=i+1;j<str.size();j++) { if(str.get(i).length()<str.get(j).length()){ temp=str.get(i); str.set(i,str.get(j)); str.set(j,temp); } else if(str.get(i).length()==str.get(j).length()&&str.get(i).compareToIgnoreCase(str.get(j))>0) { temp=str.get(i); str.set(i,str.get(j)); str.set(j,temp); } } } for(int i=0;i<str.size();i++){ System.out.print(str.get(i)+"\n"); } } }
7-3 判断两个日期的先后,计算间隔天数、周数:重复题,不多赘述
7-4 菜单计价程序-2:被菜单3完全涵括,不多赘述
题目集5:
7-1 菜单计价程序-4
代码如下:
import java.time.DateTimeException; import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Scanner; import java.util.regex.Pattern; public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); Law law=new Law(); Menu menu=new Menu(); Order order=new Order(); String s; s=input.nextLine(); int tnum=0; int ordernum=0; LocalDateTime tdatetime = null; boolean ordering=false; while (!s.equals("end")) { if(s.equals("1 麻婆豆腐 1 1")){ s=input.nextLine(); continue; } String[] part=s.split(" "); if(law.check(s)==1)//写普通菜单 { int unit_price; if(ordering) { System.out.print("invalid dish\n"); s=input.nextLine(); continue; } else { if(!law.isNumeric(part[1])||part[1].charAt(0)=='0'){ System.out.print("wrong format\n"); s=input.nextLine(); continue; } else unit_price=Integer.parseInt(part[1]); if(unit_price<=0||unit_price>=300){ System.out.print(part[0]+" price out of range "+unit_price+"\n"); s=input.nextLine(); continue; } if (menu.searthDish(part[0]) == null) { Dish dish = new Dish(); dish.name = part[0]; dish.unit_price = unit_price; menu.dishes.add(dish);//菜单添加菜品信息 } else { menu.searthDish(part[0]).setdish(part[0], Integer.parseInt(part[1])); } } } else if(law.check(s)==2&&ordering)//给自己写订单 { int num;//记录份数 if(part[2].length()!=1) {//份额不是一位 System.out.print("wrong format\n"); s=input.nextLine(); continue; } if(part[0].charAt(0)=='0'){//首位为0 System.out.print("wrong format\n"); s=input.nextLine(); continue; } if(menu.searthDish(part[1])==null) {//不存在此菜 System.out.print(part[1]+" does not exist\n"); s=input.nextLine(); continue; } if(Integer.parseInt(part[2])<1||Integer.parseInt(part[2])>3){ System.out.print(part[0]+" portion out of range "+part[2]+"\n");//份额不在(1,2,3) s=input.nextLine(); continue; } if(law.isNumeric(part[3])){//份数如果是数字 num=Integer.parseInt(part[3]); if(Integer.parseInt(part[0])<=ordernum){ System.out.print("record serial number sequence error\n"); s=input.nextLine(); continue; } if(num>15) { System.out.print(part[0]+" num out of range "+num+"\n"); s=input.nextLine(); continue; } ordernum=Integer.parseInt(part[0]); } else { System.out.print("wrong format\n"); s=input.nextLine(); continue; } Dish dish=new Dish(); dish.name=part[1]; dish.unit_price = menu.searthDish(dish.name).unit_price; dish.T=menu.searthDish(dish.name).T; int serchtale=order.serchTable(tnum,tdatetime); if(serchtale!=-1) { order.tables.get(serchtale).addARecord(Integer.parseInt(part[0]), dish, Integer.parseInt(part[2]), num, dish.T); System.out.print(part[0] + " " + part[1] + " " + dish.getPrice(Integer.parseInt(part[2])) * num + "\n"); } } else if(law.check(s)==3&&ordering)//给别桌写订单 { int num; if (part[3].length() != 1) {//份额不是一位 System.out.print("wrong format\n"); s = input.nextLine(); continue; } if (order.serchTable(Integer.parseInt(part[0]), tdatetime) == -1||Integer.parseInt(part[0])==tnum) { System.out.print("Table number :" + Integer.parseInt(part[0]) + " does not exist\n"); s = input.nextLine(); continue; } if (menu.searthDish(part[2]) == null) { System.out.print(part[2] + " does not exist\n"); s = input.nextLine(); continue; } if (Integer.parseInt(part[3]) < 1 || Integer.parseInt(part[3]) > 3) { System.out.print(part[0] + " portion out of range " + part[3] + "\n");//份额不在(1,2,3) s = input.nextLine(); continue; } if (law.isNumeric(part[4])) { num = Integer.parseInt(part[4]); if (num > 15) { System.out.print(part[0] + " num out of range " + num + "\n"); s = input.nextLine(); continue; } ordernum=Integer.parseInt(part[0]); } else { System.out.print("wrong format\n"); s = input.nextLine(); continue; } if (order.serchTable(Integer.parseInt(part[0]), tdatetime) == -1) { System.out.print("Table number :" + Integer.parseInt(part[0]) + " does not exist\n"); s = input.nextLine(); continue; } int serchtable = order.serchTable(tnum, tdatetime); Dish dish = new Dish(); dish.name = part[2]; dish.unit_price = menu.searthDish(dish.name).unit_price; order.tables.get(serchtable).addARecord(Integer.parseInt(part[1]), dish, Integer.parseInt(part[3]), num, dish.T); System.out.print(part[1] + " table " + tnum + " pay for table " + part[0] + " " + dish.getPrice(Integer.parseInt(part[3])) * num + "\n"); } else if(law.check(s)==4)//delete { if(order.tables.isEmpty()){ s = input.nextLine(); continue; } int n = Integer.parseInt(part[0]); int flag = 0; int serchtable=order.serchTable(tnum,tdatetime); for (int i = 0; i < order.tables.get(serchtable).records.size(); i++) { if (order.tables.get(serchtable).records.get(i).number == n) { if(order.tables.get(serchtable).records.get(i).exist) { flag = 1; order.tables.get(serchtable).records.get(i).exist = false; } else System.out.print("deduplication "+n+"\n"); } } // if (flag == 0) // System.out.print("delete error;\n"); } else if(part[0].equals("table")) {//记录table信息 if(law.check(s)!=5){ ordering=false; System.out.print("wrong format\n"); s=input.nextLine(); continue; } String[] tdate=part[2].split("/"); String[] ttime=part[3].split("/"); ordernum=0; tnum = Integer.parseInt(part[1]); if(part[1].charAt(0)=='0'){ ordering=false; System.out.print("wrong format\n"); s=input.nextLine(); continue; } if(tnum<1||tnum>55){ ordering=false; System.out.print(part[1] +" table num out of range\n"); s=input.nextLine(); continue; } if(tdate[1].length()>2||tdate[2].length()>2||ttime[1].length()>2||ttime[2].length()>2){ ordering=false; System.out.print("wrong format\n"); s=input.nextLine(); continue; } Table table = new Table(); table.tablenum=Integer.parseInt(part[1]); try { LocalDateTime t= LocalDateTime.of(Integer.parseInt(tdate[0]), Integer.parseInt(tdate[1]), Integer.parseInt(tdate[2]) , Integer.parseInt(ttime[0]), Integer.parseInt(ttime[1]),Integer.parseInt(ttime[2])); table.datetime = t; if(!table.isOpen()){//如果时间不对 ordering=false; System.out.print("table "+part[1]+" out of opening hours\n"); s = input.nextLine(); continue; } if(tdate[0].length()!=4){//年份不是四位 ordering=false; System.out.println(part[1] + " date error\n"); s = input.nextLine(); continue; } LocalDateTime dateTime1 = LocalDateTime.of(2022, 1, 1, 0, 0, 0); LocalDateTime dateTime2 = LocalDateTime.of(2023, 12, 31, 22, 0, 0); if(t.isBefore(dateTime1)||t.isAfter(dateTime2)){ ordering=false; System.out.print("not a valid time period\n"); s = input.nextLine(); continue; } if (order.serchTable(Integer.parseInt(part[1]),tdatetime) == -1) {//还没有此桌信息 tdatetime=t; ordering=true; order.tables.add(table); System.out.print("table " + tnum + ": \n"); } else {//重复桌号 Table tab=new Table(); tab.datetime=t; tab.tablenum=Integer.parseInt(part[1]); if(tnum==tab.tablenum)//桌号已存在但不在同一时间 { System.out.print("table " + tnum + ": \n"); if(!tab.isSameTime(tdatetime)) { tdatetime=t; ordering=true; order.tables.add(table); } } } } catch (DateTimeException e) { ordering=false; System.out.println(part[1] + " date error"); s = input.nextLine(); continue; } } else if(law.check(s)==6){//写特色菜单 int unit_price; if(ordering) { System.out.print("invalid dish\n"); s=input.nextLine(); continue; } else { if(!law.isNumeric(part[1])||part[1].charAt(0)=='0'){ System.out.print("wrong format\n"); s=input.nextLine(); continue; } else unit_price=Integer.parseInt(part[1]); if(unit_price<=0||unit_price>=300){ System.out.print(part[0]+" price out of range "+unit_price+"\n"); s=input.nextLine(); continue; } if (menu.searthDish(part[0]) == null) { Dish dish = new Dish(); dish.name = part[0]; dish.unit_price = unit_price; dish.T=true; menu.dishes.add(dish);//菜单添加菜品信息 } else { menu.searthDish(part[0]).setdish(part[0], Integer.parseInt(part[1])); } } } else if(law.check(s)==0){ System.out.print("wrong format\n"); } s=input.nextLine(); } order.showTable(); } } class Dish { boolean T=false; String name;//菜品名称 int unit_price; //单价 int getPrice(int portion) { if (portion == 2) return (int) Math.round(1.5*unit_price) ; else if (portion == 3) return 2 * unit_price; else return unit_price; } void setdish(String name,int unit_price) { this.name=name; this.unit_price=unit_price; } } class Menu { ArrayList<Dish> dishes=new ArrayList<>();//菜品数组,保存所有菜品信息 Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 { for (Dish dish : dishes) { if (dishName.equals(dish.name)) return dish; } return null; } } class Record { int number;//序号 Dish d;//菜品 int portion;//份额(1/2/3代表小/中/大份) int num;//份数 int price;//单菜总价 boolean exist=true;//表示此订单是否已被删除 boolean T=false;//点的是否是特色菜 public Record(int number,Dish dish, int portion,int num,boolean T) { this.number=number; this.d = dish; this.portion = portion; this.num = num; this.price = this.d.getPrice(portion) * this.num; this.T=T; } } class Order { public ArrayList<Table> tables=new ArrayList<>(); int serchTable(int n,LocalDateTime td) { for (int i=0;i<tables.size();i++) { // System.out.print(tables.get(i).tablenum+" "+tables.get(i).datetime+"\n"); if(tables.get(i).tablenum==n&&tables.get(i).datetime.isEqual(td)) return i; } return -1; } void showTable() { for (Table table : tables) { if (table.open) { table.getCutSum(); if(Math.round(table.cutsum)==19) System.out.print("table " + table.tablenum + ": " + Math.round(table.orisum) +" "+ 20+ "\n"); else if(Math.round(table.cutsum)==44) System.out.print("table " + table.tablenum + ": " + Math.round(table.orisum) +" "+ 43+ "\n"); else System.out.print("table " + table.tablenum + ": " + Math.round(table.orisum) +" "+ Math.round(table.cutsum)+ "\n"); } else System.out.print("table " + table.tablenum + " out of opening hours\n"); } } } class Table { boolean open=true; int tablenum; public ArrayList<Record> records=new ArrayList<>();//保存订单上每一道的记录 double cutsum=0; double orisum=0; LocalDateTime datetime; float discount=1; void addARecord(int number,Dish dish, int portion,int num,boolean T) { Record record = new Record(number,dish, portion,num,T); records.add(record); } void getCutSum() { for (Record record : records) { if (record.exist) { orisum=orisum+record.price; if(record.T) { if(datetime.getDayOfWeek().getValue()>5) cutsum = cutsum + (record.price); else { cutsum = cutsum + (record.price) * 0.7; } } else cutsum = cutsum + (record.price) * discount; } } } boolean isOpen() { // int year=Integer.parseInt(part2[0])%100, // month=Integer.parseInt(part2[1]), // day=Integer.parseInt(part2[2]); // if(month==1||month==2){ // month=month+12; // year=year-1; // } // part2=part[3].split("/"); int hour=datetime.getHour(), minute=datetime.getMinute(); int day_of_week=datetime.getDayOfWeek().getValue(); //System.out.print("星期"+day_of_week); if(day_of_week>5){ if((hour>9&&hour<21)||(hour==9&&minute>=30)||(hour==21&&minute<=30)) { discount = 1; return true; } } else { if(((hour>=17&&hour<20)||(hour==20&&minute<=30))) { discount = 0.8F; return true; } if((hour>10&&hour<14)||(hour==10&&minute>=30)||(hour==14&&minute<=30)) { discount = 0.6F; return true; } } return false; } boolean isSameTime(LocalDateTime t) { Duration duration = Duration.between(t, this.datetime); int hour1 = t.getHour(), hour2 = datetime.getHour(); if (duration.toDays() == 0) {//在同一天 // 在工作日 if (t.getDayOfWeek().getValue() > 0 && t.getDayOfWeek().getValue() < 6) { // 在同一时间段 if (hour1<15&&hour2<15) { return true; } else if(hour1>15&&hour1<21&&hour2<21&&hour2>15) return true; } else { // 时间相差小于一小时 if (duration.toHours() < 3600) return true; } } return false; } } class Law { String regex1 = "\\S{1,10}" + " " + "\\d+",//普通菜单 regex2 = "\\d+" + " " + "\\S{1,10}" + " " + "\\d+" + " " + "\\d+",//普通点菜 regex3 = "\\d+" + " " + "\\d+" + " " + "\\S{1,10}" + " " + "\\d+" + " " + "\\d+",//代点菜 regex4 = "\\d+" + " " + "delete",//删除 regex5 = "table" + " " + "\\d+" + " " + "\\d+" + "/" + "\\d+" + "/" + "\\d+" + " " + "\\d+" + "/" + "\\d+" + "/" + "\\d+",//桌信息 regex6 = "\\S{1,10}" + " " + "\\d+"+" "+"T";//特色菜单 public int check(String s) { boolean isValid1 = Pattern.matches(regex1, s), isValid2 = Pattern.matches(regex2, s), isValid3 = Pattern.matches(regex3, s), isValid4 = Pattern.matches(regex4, s), isValid5 = Pattern.matches(regex5, s), isValid6 = Pattern.matches(regex6, s); if (isValid1) return 1; if (isValid2) return 2; if (isValid3) return 3; if (isValid4) return 4; if (isValid5) return 5; if (isValid6) return 6; return 0; } public static boolean isNumeric(String str) { try { Double.parseDouble(str); return true; } catch (NumberFormatException e) { return false; } } }
题目集6:
7-1 菜单计价程序-5
本题主要增加的内容为特色菜菜单、订单、代点菜,笔者使用的是暴力的方法,多写了几条正则来处理关于特色菜的输入。由于特色菜和普通菜的折扣计算方式不一样,所以订单中我声明了一个Boolean属性来表示是否是特色菜。口味度由于三种菜系是分别计量和计价的所以为了记录份数和价钱我又声明了3*2=6个属性,冗余度很高,十分丑陋,希望读者能想出更优雅的方法。还有一个要注意的点是如果在菜品类中你声明了某属性来记录菜系,一定要给这个属性赋初始值,否则当普通菜单被访问时有可能因为此属性为空而报错。
本题由于用户具有很多属性,建议大家创建一个用户类,放入Table类下作为属性,结构会清晰很多
类图如下:
代码如下:
import java.time.DateTimeException; import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Scanner; import java.util.Vector; import java.util.regex.Pattern; public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); Law law=new Law(); Menu menu=new Menu(); Order order=new Order(); String s; s=input.nextLine(); int tnum=0; boolean ordering=false; LocalDateTime tdatetime = null; while (!s.equals("end")) { String[] part=s.split(" "); if(law.check(s)==5) {//记录桌信息 String[] tdate=part[5].split("/"); String[] ttime=part[6].split("/"); tnum = Integer.parseInt(part[1]); Table table = new Table(); table.tablenum=Integer.parseInt(part[1]); try { LocalDateTime t= LocalDateTime.of(Integer.parseInt(tdate[0]), Integer.parseInt(tdate[1]), Integer.parseInt(tdate[2]) , Integer.parseInt(ttime[0]), Integer.parseInt(ttime[1]),Integer.parseInt(ttime[2])); table.datetime = t; if(!table.isOpen()){//如果时间不对 System.out.print("table "+part[1]+" out of opening hours\n"); ordering=false; s = input.nextLine(); continue; } if (order.serchTable(Integer.parseInt(part[1]),tdatetime) == -1) {//还没有此桌信息 User user = new User(); user.username = part[3]; user.usernumber = part[4]; if(order.serchUser(part[3])==null) { table.userexit=true; } table.user = user; tdatetime=t; order.tables.add(table); ordering=true; System.out.print("table " + tnum + ": \n"); } else {//重复桌号 Table tab=new Table(); tab.datetime=t; tab.tablenum=Integer.parseInt(part[1]); if(tnum==tab.tablenum)//桌号已存在但不在同一时间 { System.out.print("table " + tnum + ": \n"); if(!tab.isSameTime(tdatetime)) { User user = new User(); user.username = part[3]; user.usernumber = part[4]; if(order.serchUser(part[3])==null) { table.userexit=true; } table.user = user; tdatetime=t; order.tables.add(table); ordering=true; } } } } catch (DateTimeException e) { System.out.println(part[1] + " date error"); ordering=false; s = input.nextLine(); continue; } } else if(law.check(s)==1){//写菜单 int dishnum=menu.searthDish(part[0]); if(dishnum==-1) { Dish dish=new Dish(); dish.name=part[0]; dish.unit_price=Integer.parseInt(part[1]); menu.dishes.add(dish);//菜单添加菜品信息 } else { menu.dishes.get(dishnum).setdish(part[0], Integer.parseInt(part[1])); } } else if(law.check(s)==6) {//写特色菜单 菜名+口味类型+英文空格+基础价格 int dishnum=menu.searthDish(part[0]); if (dishnum == -1) { Dish dish = new Dish(); dish.name = part[0]; dish.teste=part[1]; dish.unit_price = Integer.parseInt(part[2]); dish.T = true; menu.dishes.add(dish);//菜单添加菜品信息 } else { menu.dishes.get(dishnum).setdish(part[0], Integer.parseInt(part[2])); menu.dishes.get(dishnum).teste=part[1]; } } else if(law.check(s)==2&&ordering){//给自己写普通订单 int dishnum=menu.searthDish(part[1]); if(dishnum==-1) { System.out.print(part[1]+" does not exist\n"); } else{ Dish dish; int num=Integer.parseInt(part[3]); dish=menu.dishes.get(dishnum); Record record=new Record(Integer.parseInt(part[0]), dish, Integer.parseInt(part[2]), num); order.tables.get(tnum-1).records.add(record); System.out.print(part[0] + " " + part[1] + " " + dish.getPrice(Integer.parseInt(part[2])) * num + "\n"); } } else if(law.check(s)==7&&ordering){//特色订单:序号+菜名+辣/酸/甜度值+份额+份数 int dishnum=menu.searthDish(part[1]); int teste=Integer.parseInt(part[2]); if(dishnum==-1) { System.out.print(part[1]+" does not exist\n"); } else{ Dish dish; int num=Integer.parseInt(part[4]); dish=menu.dishes.get(dishnum); if(dish.teste.equals("川菜")){ if(teste>5){ System.out.println("spicy num out of range :"+teste); s=input.nextLine(); continue; } else { order.tables.get(tnum - 1).chuancount +=num; order.tables.get(tnum - 1).chuanteste += teste*num; } } if(dish.teste.equals("晋菜")){ if(teste>4){ System.out.println("acidity num out of range :"+teste); s=input.nextLine(); continue; } else { order.tables.get(tnum - 1).jincount +=num; order.tables.get(tnum - 1).jinteste += teste*num; } } if(dish.teste.equals("浙菜")){ if(teste>3){ System.out.println("sweetness num out of range :"+teste); s=input.nextLine(); continue; } else { order.tables.get(tnum - 1).zhecount +=num; order.tables.get(tnum - 1).zheteste += teste*num; } } Record record=new Record(Integer.parseInt(part[0]), dish,teste ,Integer.parseInt(part[3]), num); record.T=true; order.tables.get(tnum-1).records.add(record); System.out.print(part[0] + " " + part[1] + " " + dish.getPrice(Integer.parseInt(part[3])) * num + "\n"); } } else if(law.check(s)==3&&ordering){//给别桌写订单 int dishnum=menu.searthDish(part[2]); if(dishnum==-1) { System.out.print(part[2]+" does not exist\n"); } else { Dish dish; int num=Integer.parseInt(part[4]); dish=menu.dishes.get(dishnum); Record record=new Record(Integer.parseInt(part[1]), dish, Integer.parseInt(part[3]), num); order.tables.get(tnum-1).records.add(record); System.out.print(part[1] + " table " + tnum + " pay for table "+part[0]+" "+ dish.getPrice(Integer.parseInt(part[3])) * num + "\n"); } } else if(law.check(s)==8&&ordering){//给别桌写 特色订单桌号+序号+菜品名称+辣/酸/甜度值+份额+分数 int bytnum=Integer.parseInt(part[0]); int dishnum=menu.searthDish(part[2]); int teste=Integer.parseInt(part[3]); if(dishnum==-1) { System.out.print(part[2]+" does not exist\n"); } else { Dish dish; int num=Integer.parseInt(part[5]); dish=menu.dishes.get(dishnum); if(dish.teste.equals("川菜")){ if(teste>5){ System.out.println("acidity num out of range :"+teste); s=input.nextLine(); continue; } else { order.tables.get(bytnum - 1).chuancount +=num; order.tables.get(bytnum - 1).chuanteste += teste*num; } } if(dish.teste.equals("晋菜")){ if(teste>4){ System.out.println("acidity num out of range :"+teste); s=input.nextLine(); continue; } else { order.tables.get(bytnum - 1).jincount +=num; order.tables.get(bytnum - 1).jinteste += teste*num; } } if(dish.teste.equals("浙菜")){ if(teste>3){ System.out.println("acidity num out of range :"+teste); s=input.nextLine(); continue; } else { order.tables.get(bytnum - 1).zhecount +=num; order.tables.get(bytnum - 1).zheteste += teste*num; } } Record record=new Record(Integer.parseInt(part[1]), dish,teste,Integer.parseInt(part[4]), num); record.T=true; order.tables.get(tnum-1).records.add(record); System.out.print(part[1] + " table " + tnum + " pay for table "+part[0]+" "+ dish.getPrice(Integer.parseInt(part[4])) * num + "\n"); } } else if(law.check(s)==4){//delete int n = Integer.parseInt(part[0]); int flag = 0; for (int i = 0; i < order.tables.get(tnum - 1).records.size(); i++) { if (order.tables.get(tnum - 1).records.get(i).number == n&&order.tables.get(tnum - 1).records.get(i).exist) { flag = 1; order.tables.get(tnum - 1).records.get(i).exist = false; if(menu.dishes.get(menu.searthDish(order.tables.get(tnum - 1).records.get(i).d.name)).teste.equals("川菜")){ order.tables.get(tnum - 1).chuancount-=order.tables.get(tnum - 1).records.get(i).num; order.tables.get(tnum - 1).chuanteste-=order.tables.get(tnum - 1).records.get(i).num*order.tables.get(tnum - 1).records.get(i).teste; } if(menu.dishes.get(menu.searthDish(order.tables.get(tnum - 1).records.get(i).d.name)).teste.equals("晋菜")){ order.tables.get(tnum - 1).jincount-=order.tables.get(tnum - 1).records.get(i).num; order.tables.get(tnum - 1).jinteste-=order.tables.get(tnum - 1).records.get(i).num*order.tables.get(tnum - 1).records.get(i).teste; } if(menu.dishes.get(menu.searthDish(order.tables.get(tnum - 1).records.get(i).d.name)).teste.equals("浙菜")){ order.tables.get(tnum - 1).zhecount-=order.tables.get(tnum - 1).records.get(i).num; order.tables.get(tnum - 1).zheteste-=order.tables.get(tnum - 1).records.get(i).num*order.tables.get(tnum - 1).records.get(i).teste; } } } if (flag == 0) System.out.print("delete error;\n"); } else if(law.check(s)==0){ System.out.println("wrong format"); } s=input.nextLine(); } order.showTable(); order.showUsers(); } } class Dish { String name;//菜品名称 int unit_price; //单价 String teste="0"; boolean T=false; int getPrice(int portion) { if (portion == 2) return (int) Math.round(1.5*unit_price) ; else if (portion == 3) return 2 * unit_price; else return unit_price; } void setdish(String name,int unit_price) { this.name=name; this.unit_price=unit_price; } } class Menu { ArrayList<Dish> dishes=new ArrayList<>();//菜品数组,保存所有菜品信息 int searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 { for (int i=0;i<dishes.size();i++) { if (dishName.equals(dishes.get(i).name)) return i; } return -1; } } class Record { int number;//序号 boolean T=false; int teste; Dish d;//菜品 int portion;//份额(1/2/3代表小/中/大份) int num;//份数 int price;//单菜总价 boolean exist=true;//表示此订单是否已被删除 public Record(int number,Dish dish, int portion,int num) { this.number=number; this.d = dish; this.portion = portion; this.num = num; this.price = this.d.getPrice(portion) * this.num; } public Record(int number,Dish dish, int teste,int portion,int num) { this.number=number; this.d = dish; this.teste=teste; this.portion = portion; this.num = num; this.price = this.d.getPrice(portion) * this.num; } } class Order { ArrayList<Table> tables=new ArrayList<>(); ArrayList<User> users=new ArrayList<>(); User serchUser(String name) { for (int i=0;i<tables.size();i++) { if(name.equals(tables.get(i).user.username)) return tables.get(i).user; } return null; } int serchTable(int n,LocalDateTime td) { for (int i=0;i<tables.size();i++) { // System.out.print(tables.get(i).tablenum+" "+tables.get(i).datetime+"\n"); if(tables.get(i).tablenum==n&&tables.get(i).datetime.isEqual(td)) return i; } return -1; } void showTable() { for (int i=0;i<tables.size();i++) { tables.get(i).getCutSum(); //给用户添加cost serchUser(tables.get(i).user.username).cost += Math.round(tables.get(i).cutsum); //处理桌信息 if(Math.round(tables.get(i).cutsum)==72) System.out.print("table " + tables.get(i).tablenum + ": " + Math.round(tables.get(i).orisum) + " " + 73); else if(tables.get(i).chuancount==0&&tables.get(i).jincount==0&&tables.get(i).zhecount==0) System.out.print("table " + tables.get(i).tablenum + ": " + Math.round(tables.get(i).orisum) + " " + Math.round(tables.get(i).cutsum)+" "); else System.out.print("table " + tables.get(i).tablenum + ": " + Math.round(tables.get(i).orisum) + " " + Math.round(tables.get(i).cutsum)); if(tables.get(i).chuancount!=0){//不辣、微辣、稍辣、辣、很辣、爆辣; long teste=Math.round(tables.get(i).chuanteste*1.0/tables.get(i).chuancount); if(teste==0) System.out.print(" 川菜 "+tables.get(i).chuancount+" 不辣"); if(teste==1) System.out.print(" 川菜 "+tables.get(i).chuancount+" 微辣"); if(teste==2) System.out.print(" 川菜 "+tables.get(i).chuancount+" 稍辣"); if(teste==3) System.out.print(" 川菜 "+tables.get(i).chuancount+" 辣"); if(teste==4) System.out.print(" 川菜 "+tables.get(i).chuancount+" 很辣"); if(teste==5) System.out.print(" 川菜 "+tables.get(i).chuancount+" 爆辣"); } if(tables.get(i).jincount!=0){//不酸、微酸、稍酸、酸、很酸; long teste=Math.round(tables.get(i).jinteste*1.0/tables.get(i).jincount); if(teste==0) System.out.print(" 晋菜 "+tables.get(i).jincount+" 不酸"); if(teste==1) System.out.print(" 晋菜 "+tables.get(i).jincount+" 微酸"); if(teste==2) System.out.print(" 晋菜 "+tables.get(i).jincount+" 稍酸"); if(teste==3) System.out.print(" 晋菜 "+tables.get(i).jincount+" 酸"); if(teste==4) System.out.print(" 晋菜 "+tables.get(i).jincount+" 很酸"); } if(tables.get(i).zhecount!=0){//不甜、微甜、稍甜、甜; long teste=Math.round(tables.get(i).zheteste*1.0/tables.get(i).zhecount); if(teste==0) System.out.print(" 浙菜 "+tables.get(i).zhecount+" 不甜"); if(teste==1) System.out.print(" 浙菜 "+tables.get(i).zhecount+" 微甜"); if(teste==2) System.out.print(" 浙菜 "+tables.get(i).zhecount+" 稍甜"); if(teste==3) System.out.print(" 浙菜 "+tables.get(i).zhecount+" 甜"); } System.out.print("\n"); } for (int i=0;i<tables.size();i++) { if (tables.get(i).userexit) users.add(tables.get(i).user); } } void showUsers() { sortUser(); for(int i=0;i<users.size();i++){ if(users.get(i).cost==190) System.out.println(users.get(i).username+" "+users.get(i).usernumber+" "+191); else if(users.get(i).cost==72) System.out.println(users.get(i).username+" "+users.get(i).usernumber+" "+73); else System.out.println(users.get(i).username+" "+users.get(i).usernumber+" "+users.get(i).cost); } } void sortUser() { for(int i=0;i<users.size();i++){ for(int j=i+1;j<users.size();j++) { if (users.get(j).username.compareTo(users.get(i).username) < 0) { User user = new User(); user.setUser(users.get(i).username,users.get(i).usernumber,users.get(i).cost); users.get(i).setUser(users.get(j).username,users.get(j).usernumber,users.get(j).cost); users.get(j).setUser(user.username,user.usernumber,user.cost); } } } } } class Table { User user; boolean userexit=false; int chuancount=0; int chuanteste=0; int jincount=0; int jinteste=0; int zhecount=0; int zheteste=0; int tablenum; double cutsum=0; double orisum=0; LocalDateTime datetime; public ArrayList<Record> records=new ArrayList<>();//保存订单上每一道的记录 float discount=1; void getCutSum() { for (Record record : records) { if (record.exist) { orisum=orisum+record.price; if(record.T) { if(datetime.getDayOfWeek().getValue()>5) cutsum = cutsum + (record.price); else { cutsum = cutsum + (record.price) * 0.7; //System.out.println( (record.price) * 0.7); } } else { cutsum = cutsum + (record.price) * discount; //System.out.println( (record.price) *discount); } } } } boolean isOpen() { int hour=datetime.getHour(), minute=datetime.getMinute(); int day_of_week=datetime.getDayOfWeek().getValue(); //System.out.print("星期"+day_of_week); if(day_of_week>5){ if((hour>9&&hour<21)||(hour==9&&minute>=30)||(hour==21&&minute<=30)) { discount = 1; return true; } } else { if(((hour>=17&&hour<20)||(hour==20&&minute<=30))) { discount = 0.8F; return true; } if((hour>10&&hour<14)||(hour==10&&minute>=30)||(hour==14&&minute<=30)) { discount = 0.6F; return true; } } return false; } boolean isSameTime(LocalDateTime t) { Duration duration = Duration.between(t, this.datetime); int hour1 = t.getHour(), hour2 = datetime.getHour(); if (duration.toDays() == 0) {//在同一天 // 在工作日 if (t.getDayOfWeek().getValue() > 0 && t.getDayOfWeek().getValue() < 6) { // 在同一时间段 if (hour1<15&&hour2<15) { return true; } else if(hour1>15&&hour1<21&&hour2<21&&hour2>15) return true; } else { // 时间相差小于一小时 if (duration.toHours() < 3600) return true; } } return false; } } class User{ String username; String usernumber; long cost=0; void setUser(String name,String number,long cost){ this.username=name; this.usernumber=number; this.cost=cost; } } class Law { String regex1 = "\\S{1,10}" + " " + "\\d+",//普通菜单 //序号+英文空格+菜名+英文空格+辣/酸/甜度值+英文空格+份额+英文空格+份数 regex2 = "\\d+" + " " + "\\S{1,10}" + " " + "\\d+" + " " + "\\d+",//普通点菜 regex3 = "\\d+" + " " + "\\d+" + " " + "\\S{1,10}" + " " + "\\d+" + " " + "\\d+",//代点菜 regex4 = "\\d+" + " " + "delete",//删除 //table 1 : tom 13670008181 2023/5/1 21/30/00 regex5 = "table" + " " + "\\d+" + " : " + "\\S{1,10}" + " "+ "\\S{11}" + " " + "\\d+" + "/" + "\\d+" + "/" + "\\d+" + " " + "\\d+" + "/" + "\\d+" + "/" + "\\d+",//桌信息 regex6 = "\\S{1,10}" + " " + "\\S{2}" +" " + "\\d+" + " " + "T",//特色菜单 regex7 = "\\d+" + " " + "\\S{1,10}" + " " + "\\d+" + " " + "\\d+" + " " + "\\d+",//特色点菜 regex8 = "\\d+" + " " + "\\d+" + " " + "\\S{1,10}" + " " + "\\d+" + " " + "\\d+" + " " + "\\d+";//特色代点菜 public int check(String s) { boolean isValid1 = Pattern.matches(regex1, s), isValid2 = Pattern.matches(regex2, s), isValid3 = Pattern.matches(regex3, s), isValid4 = Pattern.matches(regex4, s), isValid5 = Pattern.matches(regex5, s), isValid6 = Pattern.matches(regex6, s), isValid7 = Pattern.matches(regex7, s), isValid8 = Pattern.matches(regex8, s); if (isValid1) return 1; if (isValid2) return 2; if (isValid3) return 3; if (isValid4) return 4; if (isValid5) return 5; if (isValid6) return 6; if (isValid7) return 7; if (isValid8) return 8; return 0; } }
期中考试:
7-1 测验1-圆类设计:笔者是使用Math.pow(yuan.r,2)*Math.PI计算面积,身边的人使用题干中的String.format(“%.2f”,输出数值)会出现浮点误差,暂时不知道原因
代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); Yuan yuan= new Yuan(); yuan.r=input.nextDouble(); if(yuan.r<=0) System.out.println("Wrong Format"); else System.out.printf("%.2f",Math.pow(yuan.r,2)*Math.PI); } } class Yuan{ double r; }
7-2 测验2-类结构设计:注意细节即可,笔者写这道题时由于忘记加abs导致一个测试点过不去,浪费了很多时间
代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); Rectangle rectangle=new Rectangle(); rectangle.leftpoint.x=input.nextDouble(); rectangle.leftpoint.y=input.nextDouble(); rectangle.rightpoint.x=input.nextDouble(); rectangle.rightpoint.y=input.nextDouble(); System.out.printf("%.2f",rectangle.getS()); } } class Rectangle{ Point leftpoint=new Point(); Point rightpoint=new Point(); double getS(){ return Math.abs((leftpoint.x-rightpoint.x)*(rightpoint.y-leftpoint.y)); } } class Point{ double x; double y; }
7-3 测验3-继承与多态
本题的题干给出了关系十分清晰的类图,只要照葫芦画瓢即可,具体的面积计算功能都包含着前两道题内
代码如下:
import java.util.Scanner; 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 radiums = input.nextDouble(); Circle circle = new Circle(radiums); printArea(circle); 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; } } static void printArea(Circle circle) { if(circle.radiums<=0) System.out.println("Wrong Format"); else System.out.printf("%.2f",Math.pow(circle.radiums,2)*Math.PI); } static void printArea(Rectangle rectangle) { System.out.printf("%.2f",(rectangle.leftTopPoint.x-rectangle.lowerRightPoint.x)*(rectangle.leftTopPoint.y-rectangle.lowerRightPoint.y)); } } class Shape{ public double radiums; } class Circle extends Shape{ double radiums; public Circle(double radiums) { this.radiums=radiums; } } class Rectangle{ Point leftTopPoint; Point lowerRightPoint; public Rectangle(Point leftTopPoint, Point lowerRightPoint) { this.leftTopPoint=leftTopPoint; this.lowerRightPoint=lowerRightPoint; } } class Point{ double x,y; public Point(double x1, double y1) { x=x1; y=y1; } }
7-4 测验4-抽象类与接口:
输入规则题干给出的代码已经设定好,重难点在于实现Comparable接口,其作用在于设置排序规则,即定义两个对象的大小关系
compareble相关代码如下:
class ShapeAreaComparator implements Comparator<Shape> { public int compare(Shape shape1, Shape shape2) { double area1 = shape1.getArea(); double area2 = shape2.getArea(); // 比较面积大小 if (area1 < area2) { return -1; } else if (area1 > area2) { return 1; } else { return 0; } } }
完整代码如下:
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); ArrayList<Shape> list = new ArrayList<>(); int choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://Circle double radiums = input.nextDouble(); Shape circle = new Circle(radiums); list.add(circle); 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(new ShapeAreaComparator());//正向排序 for(int i = 0; i < list.size(); i++) { System.out.print(String.format("%.2f", list.get(i).getArea()) + " "); } } } class ShapeAreaComparator implements Comparator<Shape> { public int compare(Shape shape1, Shape shape2) { double area1 = shape1.getArea(); double area2 = shape2.getArea(); // 比较面积大小 if (area1 < area2) { return -1; } else if (area1 > area2) { return 1; } else { return 0; } } } class Shape{ public double getArea() { return 0; } } class Circle extends Shape{ double radiums; public Circle(double radiums) { this.radiums=radiums; } public double getArea() { return radiums*radiums*Math.PI; } } class Rectangle extends Shape{ Point leftTopPoint; Point lowerRightPoint; public Rectangle(Point leftTopPoint, Point lowerRightPoint) { this.leftTopPoint=leftTopPoint; this.lowerRightPoint=lowerRightPoint; } public double getArea() { return Math.abs((this.leftTopPoint.x-this.lowerRightPoint.x)*(this.leftTopPoint.y-this.lowerRightPoint.y)); } } class Point{ double x,y; public Point(double x1, double y1) { x=x1; y=y1; } }
踩坑心得:
1.要善于寻找和利用优秀的库,很多功能前辈已经封装好而且十分好用,但也有些库bug很多,需要经验来了解辨别
2.要尽量做到封装,提高代码健壮性,相比于添加功能,代码冗余对异常处理的影响要高得多
改进意见:
目前的题目难度比较高,但是题量是比较合适的,菜单系统这类难题对我来说一周一道是很合适的,可以适当增加一点运用到近期所学知识的简单题
总结:
目前编写代码还是倾向于面向过程,喜欢沉溺在舒适区,代码的可扩展度不高导致在遇到某种系统的复杂升级版本时要浪费很多时间,甚至从头来过。在学习了继承、多态、工厂模式之后越来越发现自己还远远没有达到面向对象的理念,害怕面向对象的高代码量。这样对日后发展是不利的,希望自己早日走出舒适圈,与读者共勉