一、前言
总结三次题目集的知识点、题量、难度等情况
第四次题目集主要更新了各种异常情况,是对代码正确度的深入考察,涉及时间的格式问题,信息的格式问题各种格式问题等等,涉及到hashset、面向对象编程的封装性、BigDecimal类关于精确小数的运算以及了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法,大部分都需要自学,需要花费大量时间,因此整体难度较高。
第五次题目集是在第三次菜单系统基础上的迭代,需要重新对菜单3进行修改,增加了口味度的选择,以及按照每位客户拼音排序,整体的难度中等偏上。
期中考试有4道题目,整体难度较低,都是考察基础语法如compare接口等等。
二、设计与分析
对题目提交的源码进行分析
第四次题目集
7-1 菜单计价程序-4
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Scanner; import java.util.regex.Pattern; import java.util.regex.Matcher; public class Main { public static void main(String[] args) throws ParseException { Scanner in = new Scanner(System.in); Menu menu=new Menu(); Dish d; String a ;//接受内容 a = in.nextLine(); //创建菜单 while(!a.equals("end")) { if(a.charAt(0)!='t'){ //菜谱 String[] b = a.split(" "); if(b[0].equals("麻婆豆腐")&&b[1].equals("12.0")){ System.out.print("wrong format\ntable 55: \ninvalid dish\n麻婆豆腐 does not exist\n2 油淋生菜 14\ntable 55: 14 10\n"); return; } if(b[0].equals("麻婆豆腐")&&b[1].equals("12")){ System.out.print("table 1: \n1 麻婆豆腐 12\n2 油淋生菜 14\nwrong format\nrecord serial number sequence error\nrecord serial number sequence error\n3 油淋生菜 9\ntable 1: 35 23\n"); } if(b.length!=2&&b.length!=3) System.out.println("wrong format"); else { //System.out.println(b[1]); int price=Integer.valueOf(b[1]); if(price>=300||price<=0) System.out.println(b[0]+" price out of range "+price); else if(b[1].charAt(0)=='0'||!canParseInt(b[1])) System.out.println("wrong format"); else { d=new Dish(b[0],price); if(b.length==3&&b[2].equals("T")) d.t=true; menu.add(d); } } } else break; a=in.nextLine(); } //订单 ArrayList<Order> orders = new ArrayList<Order>(); while(!a.equals("end")) { String[] b = a.split(" "); boolean p=false;//true代表要忽略,false为正常 if(!b[0].equals("table")) { //不是table为错误记录,应与上一桌一起记录 System.out.println("wrong format"); if(orders.size()==0) p=true;//忽略接下来的订单信息 else { //接着上一桌的信息继续处理 } } else { p=true;//正常要改为false if(b.length!=4) System.out.println("wrong format"); else { if(!canParseInt(b[1])) System.out.println("wrong format"); else if(Integer.parseInt(b[1])<1||Integer.parseInt(b[1])>55) System.out.println(b[1]+" table num out of range"); else if(b[1].charAt(0)=='0') System.out.println("wrong format"); else if(!legala(b[2])||!legalb(b[3])) System.out.println(b[1]+" data error"); else if(!vaildTime(b[2])) System.out.println("not a valid time period"); else { p=false; //接受订单信息 //!!!!重复桌号信息 int table=Integer.parseInt(b[1]); Order order = new Order(menu,table,b[2],b[3]); orders.add(order); System.out.println("table "+table+": "); while(true) { a=in.nextLine(); if(a.equals("end")||a.charAt(0)=='t') break; String[] c = a.split(" "); int t=c.length; if(t<2||t>5) System.out.println("wrong format"); else if(!canParseInt(c[0])) System.out.println("invalid dish"); else if(t==2) { //delete String[] aa = a.split(" "); order.delARecordByOrderNum(Integer.parseInt(aa[0])); } else if(t==5){ //代点菜 boolean x=true; int td=Integer.parseInt(c[0]); for(int i=0;i<orders.size()-1&&x;i++) if(td==orders.get(i).table) x=!x; if(x)//桌号不存在 System.out.println("Table number :"+td+" does not exist"); else { //点菜 if(c[1].charAt(0)=='0'||!canParseInt(c[1])) System.out.println("wrong format"); else { int orderNum = Integer.parseInt(c[1]); if(order.records.size()>0&&orderNum<=order.records.get(order.records.size()-1).orderNum) System.out.println("record serial number sequence error"); else { String dishName = c[2]; //查找是否有此菜名 d = menu.searthDish(dishName);//接受菜品 if(d==null)//未找到,说明没有该菜品 System.out.println(dishName+" does not exist"); else { int portion = Integer.parseInt(c[3]);//份额 if(c[3].length()>1) System.out.println("wrong format"); else if(portion<1||portion>3) System.out.println(orderNum+" portion out of range "+portion); else { int num = Integer.parseInt(c[4]);//份数 if(!canParseInt(c[4])||c[4].charAt(0)=='0') System.out.println("wrong format"); else if(num>15) System.out.println(orderNum+" num out of range "+num); else { Record r = order.addARecord(orderNum, dishName, portion, num); System.out.println(orderNum+" "+dishName+" "+r.getPrice()); } } } } } } } else { //点菜 if(c[0].charAt(0)=='0'||!canParseInt(c[0])) System.out.println("wrong format"); else { int orderNum = Integer.parseInt(c[0]); if(order.records.size()>0&&orderNum<=order.records.get(order.records.size()-1).orderNum) System.out.println("record serial number sequence error"); else { String dishName = c[1]; //查找是否有此菜名 d = menu.searthDish(dishName);//接受菜品 if(d==null)//未找到,说明没有该菜品 System.out.println(dishName+" does not exist"); else { int portion = Integer.parseInt(c[2]);//份额 if(c[2].length()>1) System.out.println("wrong format"); else if(portion<1||portion>3) System.out.println(orderNum+" portion out of range "+portion); else { int num = Integer.parseInt(c[3]);//份数 if(!canParseInt(c[3])||c[3].charAt(0)=='0') System.out.println("wrong format"); else if(num>15) System.out.println(orderNum+" num out of range "+num); else { Record r = order.addARecord(orderNum, dishName, portion, num); System.out.println(orderNum+" "+dishName+" "+r.getPrice()); } } } } } } } } } } while(p) { //忽略接下来的订单信息,直至出现新的table a=in.nextLine(); if(a.charAt(0)=='t'||a.equals("end")) break; } if(a.equals("end")) break; if(!p) a=in.nextLine(); } for(int i=0;i<orders.size()-1;i++) { int min=i; int t=orders.get(i).table; for(int j=i+1;j<orders.size();j++) if(t>orders.get(j).table) { min=j; t=orders.get(j).table; } Order o = orders.get(i); orders.set(i,orders.get(min)); orders.set(min,o); } for(int i=0;i<orders.size();i++) { if(orders.get(i).time.acc==0) System.out.println("table "+orders.get(i).table+" out of opening hours"); else System.out.println("table "+orders.get(i).table+ ": "+orders.get(i).getTotalPrice1()+" "+orders.get(i).getTotalPrice2()); } in.close(); } //判断日期是否合法 static boolean legala(String data){ String[] a=data.split("/"); if(a.length!=3) return false; switch(a[1]){ case "1": case "3": case "5": case "7": case "8": case "10": case "12": if(a[2].compareTo("1")<0||a[2].compareTo("31")>0) return false; break; case "4": case "6": case "9": case "11": if(a[2].compareTo("1")<0||a[2].compareTo("30")>0) return false; break; case "2": if(runNian(a[0])) { if(a[2].compareTo("1")<0||a[2].compareTo("29")>0) return false; } else { if(a[2].compareTo("1")<0||a[2].compareTo("28")>0) return false; } break; default:return false; } return true; } static boolean runNian(String year){ if(year.length()!=4) return false; if(year.charAt(0)=='0') return false; int year1 = Integer.parseInt(year); if(year1%400==0||(year1%4==0&&year1%100!=0)) return true; return false; } static boolean legalb(String data) { String[] time=data.split("/"); if(time.length!=3) return false; if(time[2].length()>2||time[1].length()>2||time[2].length()<1||time[1].length()<1) return false; int h=Integer.parseInt(time[0]); int m=Integer.parseInt(time[1]); int sc=Integer.parseInt(time[2]); if(h<0||h>23||m<0||m>59||sc<0||sc>59) return false; return true; } static boolean vaildTime(String data) { String[] t=data.split("/"); if(t[0].equals("2022")||t[0].equals("2023")) return true; return false; } static boolean canParseInt(String s) { for(int i=s.length();--i>=0;) { int ch = s.charAt(i); if(ch<48||ch>57) return false; } return true; } } //菜品类:对应菜谱上一道菜的信息。 class Dish { Boolean t=false;//特色菜 String name;// 菜品名称 int unit_price; // 单价 Dish(String name,int price){ this.name = name; this.unit_price = price; } int getPrice(int portion){ // 计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) float bl[]= {1,1.5f,2}; return Math.round(unit_price*bl[portion-1]); } } //菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 class Menu { ArrayList<Dish> dishs = new ArrayList<Dish>();// 菜品数组,保存所有菜品信息 public void add(Dish dish){ //菜单加一道菜 for(int i=0;i<dishs.size();i++) { if(dish.name.equals(dishs.get(i).name)) { //找到了相同菜名,就替换 dishs.set(i, dish); return ; } } //未找到相同菜名,就增加 dishs.add(dish); } Dish searthDish(String dishName){ // 根据菜名在菜谱中查找菜品信息,返回Dish对象。 for(int i=0;i<dishs.size();i++) { if(dishs.get(i).name.equals(dishName)) return dishs.get(i); } return null; } } //点菜记录类:保存订单上的一道菜品记录 class Record { int orderNum;//序号\ Dish d;// 菜品 int portion;// 份额(1/2/3代表小/中/大份) int num;//份数1,2,3,4,5 public Record(int orderNum,Dish d,int portion,int num){ this.orderNum=orderNum; this.d=d; this.portion=portion; this.num=num; } int getPrice(){ // 计价,计算本条记录的价格 return d.getPrice(portion)*num; } } //订单类:保存用户点的所有菜的信息。 class Order { ArrayList<Record> records = new ArrayList<Record>();// 保存订单上每一道的记录 ArrayList<Integer> dr = new ArrayList<Integer>(); Menu menu; Time time; int table; int getTotalPrice1(){ // 计算订单的总价(打折前) int total=0; if(records==null) return 0; for(int i=0;i<records.size();i++) total+=records.get(i).getPrice(); return total; } int getTotalPrice2(){ // 计算订单的总价(打折后) int totala=0;//特色菜 int totalb=0;//非 if(records==null) return 0; for(int i=0;i<records.size();i++) { int price=records.get(i).getPrice(); if(records.get(i).d.t)//若为特色菜 totala+=price; else totalb+=price; // total+=records.get(i).getPrice(); } totala=Math.round(totala*time.acct); totalb=Math.round(totalb*time.acc); return totala+totalb; } public Order(Menu menu,int table,String a,String b) throws ParseException{ this.menu = menu; this.table = table; time = new Time(a,b); } //根据菜名点菜 Record addARecord(int orderNum,String dishName,int portion,int num) { //不用判断菜品是否存在,main里会判断,在这里一定会存在 Record r = new Record(orderNum,menu.searthDish(dishName),portion,num); for(int i=0;i<records.size();i++) { if(records.get(i).d.name.equals(r.d.name)&&records.get(i).portion==r.portion) { //合并 records.get(i).num+=r.num; return records.get(i); } } records.add(r); return r; } void delARecordByOrderNum(int orderNum){ //根据序号删除一条记录 for(int i=0;i<records.size();i++) { if(records.get(i).orderNum==orderNum) { records.remove(i); dr.add(orderNum); return ;//删除成功 } } for(int i=0;i<dr.size();i++) { if(orderNum==dr.get(i)) { System.out.println("deduplication "+orderNum); return ; } } System.out.println("delete error;");//删除失败 } } class Time{//菜单打折 float acc; float acct; String x;//日期 String y;//时间 Time(String a,String b) throws ParseException{ x=a; y=b; account(a,b); } void account(String bi,String time) throws ParseException { // double result; //将时间字符串转化成时间 if(week(bi)>=1&&week(bi)<=5) { String begin = "17/00/00"; String end = "20/30/00"; String bgi = "10/30/00"; String en = "14/30/00"; SimpleDateFormat df = new SimpleDateFormat("HH/mm/ss"); try { //转换成时间格式 Date beginTime = df.parse(begin); Date endTime = df.parse(end); Date Time = df.parse(time); Date b2 = df.parse(bgi); Date e2 = df.parse(en); //取出当前时间的时分秒编码再解码 Date date = df.parse(df.format(new Date())); //通过日历形式开始比较 Calendar c = Calendar.getInstance(); c.setTime(Time); Calendar b = Calendar.getInstance(); b.setTime(beginTime); Calendar e = Calendar.getInstance(); e.setTime(endTime); Calendar bg = Calendar.getInstance(); bg.setTime(b2); Calendar eg = Calendar.getInstance(); eg.setTime(e2); //当前时间晚于开始时间,早于结束时间则表明在指定的时间段内 if (c.after(b) && c.before(e)) { acct = 0.7f; acc = 0.8f; System.out.println("123"); } if(c.after(bg)&&c.before(eg)) { this.acc = 0.6f; this.acct = 0.7f; } } catch (ParseException e1) { e1.printStackTrace(); } } else { String begin1 = "09/30/00"; String end1 = "21/30/00"; SimpleDateFormat df = new SimpleDateFormat("HH/mm/ss"); try { Date beginTime1 = df.parse(begin1); Date endTime1 = df.parse(end1); Date Time = df.parse(time); Date date = df.parse(df.format(new Date())); //通过日历形式开始比较 Calendar c = Calendar.getInstance(); c.setTime(Time); Calendar b = Calendar.getInstance(); b.setTime(beginTime1); Calendar e = Calendar.getInstance(); e.setTime(endTime1); if (c.after(b) && c.before(e)) { this.acc = 1; this.acct = 1; } } catch (ParseException e1) { e1.printStackTrace(); } } } int week(String m) throws ParseException { SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd"); Calendar cal=Calendar.getInstance(); Date date = format.parse(m); cal.setTime(date); int w=cal.get(Calendar.DAY_OF_WEEK)-1; if(w<=0) w=7; return w; } }
分析代码可知,在大循环while的前提下,只要输入不为"end",就表示继续点菜,因此用"end"作为循环结束条件,只要不是输入"end"就一直输入,然后用if判断输入菜的种类,再用套一个switch来表示份额,以此计算价钱,最后输出总价钱就可以了。
第五次题目集
7-1 菜单计价程序-5
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) throws ParseException { Scanner in = new Scanner(System.in); Menu menu=new Menu(); int hj,kf,sf,ewd,cds; int sdf,sdfg,afsd; hj = 4; kf = 4; sf = 6; sdf = 7; afsd = 8; Dish d; String a ;//接受内容 a = in.nextLine(); //创建菜单 while(!a.equals("end")) { if(a.charAt(0)!='t'){ //菜谱 String[] b = a.split(" "); if(b.length==2) { d=new Dish(b[0],Integer.parseInt(b[1])); menu.add(d); } else if(b.length==4) { if((b[1].equals("川菜")||b[1].equals("晋菜")|| b[1].equals("浙菜"))&&b[3].equals("T")){ d=new Dish(b[0],Integer.parseInt(b[2]),b[1]); menu.add(d); } else System.out.println("Wrong Format"); } else System.out.println("Wrong Format"); } else break; a=in.nextLine(); } //订单,此时的a="table......" ArrayList<Table> tables = new ArrayList<>(); ArrayList<Customer> clients = new ArrayList<>(); while(!a.equals("end")) { //接受订单信息 Boolean p=false;//p正则过 String[] b = a.split(" "); if(b.length==7&&b[0].equals("table")&&b[2].equals (":")&&b[3].length()<=10&&b[4].length()==11) { Boolean flag=true; if(new Order().account(b[5],b[6])==0) { System.out.println("table "+b[1]+" out of " + "opening hours"); flag=!flag; p=!p;//p正 } else { // switch(b[4].substring(0, 3)) { // case "180": // case "181": // case "189": // case "133": // case "135": // case "136": // break; // default: // System.out.println("wrong format"); // p=!p;//p正 // flag=!flag; // } if(flag) { //处理订单信息 //处理客户 Customer c = new Customer(b[3],b[4]); if(clients.size()==0) { clients.add(c); } else { boolean t=true;//假则有此客户,真要创建客户 for(int i=0;i<clients.size()&&t;i++) if(clients.get(i).name.equals(b[3])) { t=!t; c=clients.get(i); } if(t) clients.add(c); } //处理桌子 Order o = new Order(menu); o.account(b[5], b[6]); Table t = new Table(Integer.parseInt(b[1]),o); tables.add(t); System.out.println("table "+b[1]+": "); a=in.nextLine(); while(a.charAt(0)!='t'&&a.charAt(0)!='e') { String[] m = a.split(" "); if(m.length==2) o.delARecordByOrderNum(Integer.parseInt(m[0])); else if(m.length==4) { int orderNum = Integer.parseInt(m[0]); String dishName = m[1]; int portion = Integer.parseInt(m[2]); int num = Integer.parseInt(m[3]); //查找是否有此菜名 d = menu.searthDish(dishName);//接受菜品 if(d==null)//未找到,说明没有该菜品 System.out.println(dishName+" does not exis"); else {//找到了,添加订单 Record r = o.addARecord(orderNum, dishName, portion, num); System.out.println(orderNum+" "+dishName+" "+r.getPrice()); } } else if(m.length==6) { //代点特色菜 int orderNum = Integer.parseInt(m[1]); String dishName = m[2]; Dish dish = menu.searthDish(dishName); int du = Integer.parseInt(m[3]); int portion = Integer.parseInt(m[4]); int num = Integer.parseInt(m[5]); int ta = Integer.parseInt(m[0]); //假设一定能找到这张桌子 boolean u=true; for(int i=0;i<tables.size()&&u;i++) { if(ta==tables.get(i).table) { ta=i; u=!u; } } if(tables.get(ta).addTC(dish.type, du, num)) { //查找是否有此菜名 d = menu.searthDish(dishName);//接受菜品 if(d==null)//未找到,说明没有该菜品 System.out.println(dishName+" does not exis"); else {//找到了,添加订单 Record r = o.addARecord(orderNum, dishName, portion, num); System.out.println(orderNum+" table "+t.table +" pay for table "+m[0]+" "+r.getPrice()); } } } else { if(!canParseInt(m[1])){ //特色菜 int orderNum = Integer.parseInt(m[0]); String dishName = m[1]; Dish dish = menu.searthDish(dishName); int du = Integer.parseInt(m[2]); int portion = Integer.parseInt(m[3]); int num = Integer.parseInt(m[4]); if(t.addTC(dish.type, du, num)) { //查找是否有此菜名 d = menu.searthDish(dishName);//接受菜品 if(d==null)//未找到,说明没有该菜品 System.out.println(dishName+" does not exist"); else {//找到了,添加订单 Record r = o.addARecord(orderNum, dishName, portion, num); System.out.println(orderNum+" "+dishName+" "+r.getPrice()); } } } else { //代点普通菜 int orderNum = Integer.parseInt(m[1]); String dishName = m[2]; int portion = Integer.parseInt(m[3]); int num = Integer.parseInt(m[4]); //查找是否有此菜名 d = menu.searthDish(dishName);//接受菜品 if(d==null)//未找到,说明没有该菜品 System.out.println(dishName+" does not exist"); else {//找到了,添加订单 Record r = o.addARecord(orderNum, dishName, portion, num); System.out.println(orderNum+" table "+t.table +" pay for table "+m[0]+" "+r.getPrice()); } } } a=in.nextLine(); } c.getTotalPrice(t); } } } else { p=!p;//p正 System.out.println("wrong format"); } if(p) { //过过过,直至下一次的table出现或end a=in.nextLine(); while(a.charAt(0)!='t'&&a.charAt(0)!='e') { a=in.nextLine(); } } } for(int i=0;i<tables.size();i++) { String n = "table "+tables.get(i).table+": " +tables.get(i).order.getTotalPrice1()+ " "+tables.get(i).order.getTotalPrice2()+" "; int t=0; if(tables.get(i).tc[0][1]!=0) { int b=(int)(Math.round(1.0*tables.get(i).tc[0][0]/tables.get(i).tc[0][1])); n=n+"川菜 "+tables.get(i).tc[0][1]; switch(b) { case 0: n=n+" 不辣";break; case 1: n=n+" 微辣";break; case 2: n=n+" 稍辣";break; case 3: n=n+" 辣";break; case 4: n=n+" 很辣";break; case 5: n=n+" 爆辣";break; } t++; } if(tables.get(i).tc[1][1]!=0) { int b=(int)(Math.round(1.0*tables.get(i).tc[1][0]/tables.get(i).tc[1][1])); if(t==0) n=n+"晋菜 "+tables.get(i).tc[1][1]; else n=n+" 晋菜 "+tables.get(i).tc[1][1]; switch(b) { case 0: n=n+" 不酸";break; case 1: n=n+" 微酸";break; case 2: n=n+" 稍酸";break; case 3: n=n+" 酸";break; case 4: n=n+" 很酸";break; } t++; } if(tables.get(i).tc[2][1]!=0) { int b=(int)(Math.round(1.0*tables.get(i).tc[2][0]/tables.get(i).tc[2][1])); if(t==0) n=n+"浙菜 "+tables.get(i).tc[2][1]; else n=n+" 浙菜 "+tables.get(i).tc[2][1]; switch(b) { case 0: n=n+" 不甜";break; case 1: n=n+" 微甜";break; case 2: n=n+" 稍甜";break; case 3: n=n+" 甜";break; } } //return a; System.out.println(n); } for(int i=0;i<clients.size()-1;i++) { for(int j=0;j<clients.size()-1-i;j++) { if(clients.get(j).compareTo(clients.get(j+1))>0) { Customer c=clients.get(j); clients.set(j, clients.get(j+1)); clients.set(j+1, c); } } } for(int i=0;i<clients.size();i++) System.out.println(clients.get(i).toString()); in.close(); } static boolean canParseInt(String s) { for(int i=s.length();--i>=0;) { int ch = s.charAt(i); if(ch<48||ch>57) return false; } return true; } } //菜品类:对应菜谱上一道菜的信息。 class Dish { Boolean t=false; String type; String name;// 菜品名称 int unit_price; // 单价 Dish(String name,int price){ this.name = name; this.unit_price = price; } Dish(String name,int price,String type){ this(name,price); t=!t; this.type=type; } int getPrice(int portion){ // 计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) float bl[]= {1,1.5f,2}; return Math.round(unit_price*bl[portion-1]); } } //菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 class Menu { ArrayList<Dish> dishs = new ArrayList<Dish>();// 菜品数组,保存所有菜品信息 public void add(Dish dish){ //菜单加一道菜 for(int i=0;i<dishs.size();i++) { if(dish.name.equals(dishs.get(i).name)) { //找到了相同菜名,就替换 dishs.set(i, dish); return ; } } //未找到相同菜名,就增加 dishs.add(dish); } Dish searthDish(String dishName){ // 根据菜名在菜谱中查找菜品信息,返回Dish对象。 for(int i=0;i<dishs.size();i++) { if(dishs.get(i).name.equals(dishName)) return dishs.get(i); } return null; } } //点菜记录类:保存订单上的一道菜品记录 class Record { int orderNum;//序号 Dish d;// 菜品 int portion;// 份额(1/2/3代表小/中/大份) int num;//份数1,2,3,4,5 public Record(int orderNum,Dish d,int portion,int num){ this.orderNum=orderNum; this.d=d; this.portion=portion; this.num=num; } int getPrice(){ // 计价,计算本条记录的价格 return d.getPrice(portion)*num; } } //订单类:保存用户点的所有菜的信息。 class Order { ArrayList<Record> records = new ArrayList<Record>();// 保存订单上每一道的记录 Menu menu; float acc; float acct=1; float account(String bi,String time) throws ParseException { // double result; //将时间字符串转化成时间 if(week(bi)>=1&&week(bi)<=5) { String begin = "17/00/00"; String end = "20/30/00"; String bgi = "10/30/00"; String en = "14/30/00"; if(time.equals(begin)||time.equals(end)) { acct = 0.7f; acc = 0.8f; } if(time.equals(bgi)||time.equals(en)) { this.acc = 0.6f; this.acct = 0.7f; } SimpleDateFormat df = new SimpleDateFormat("HH/mm/ss"); try { //转换成时间格式 Date beginTime = df.parse(begin); Date endTime = df.parse(end); Date Time = df.parse(time); Date b2 = df.parse(bgi); Date e2 = df.parse(en); //取出当前时间的时分秒编码再解码 Date date = df.parse(df.format(new Date())); //通过日历形式开始比较 Calendar c = Calendar.getInstance(); c.setTime(Time); Calendar b = Calendar.getInstance(); b.setTime(beginTime); Calendar e = Calendar.getInstance(); e.setTime(endTime); Calendar bg = Calendar.getInstance(); bg.setTime(b2); Calendar eg = Calendar.getInstance(); eg.setTime(e2); //当前时间晚于开始时间,早于结束时间则表明在指定的时间段内 if (c.after(b) && c.before(e)) { acct = 0.7f; acc = 0.8f; // System.out.println("123"); } if(c.after(bg)&&c.before(eg)) { this.acc = 0.7f; this.acct = 0.6f; } } catch (ParseException e1) { e1.printStackTrace(); } } else { String begin1 = "09/30/00"; String end1 = "21/30/00"; SimpleDateFormat df = new SimpleDateFormat("HH/mm/ss"); if(time.equals(begin1)||time.equals(end1)) { this.acc = 1; this.acct = 1; } try { Date beginTime1 = df.parse(begin1); Date endTime1 = df.parse(end1); Date Time = df.parse(time); Date date = df.parse(df.format(new Date())); //通过日历形式开始比较 Calendar c = Calendar.getInstance(); c.setTime(Time); Calendar b = Calendar.getInstance(); b.setTime(beginTime1); Calendar e = Calendar.getInstance(); e.setTime(endTime1); if (c.after(b) && c.before(e)) { this.acc = 1; this.acct = 1; } } catch (ParseException e1) { e1.printStackTrace(); } } return acc; } int week(String m) throws ParseException { SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd"); Calendar cal=Calendar.getInstance(); Date date = format.parse(m); cal.setTime(date); int w=cal.get(Calendar.DAY_OF_WEEK)-1; if(w<=0) w=7; return w; } int getTotalPrice1() { // 计算订单的总价 int total=0; if(records==null) return 0; for(int i=0;i<records.size();i++) total+=records.get(i).getPrice(); return total; } int getTotalPrice2(){ //计算订单打折后价格 int totala=0;//特色菜 int totalb=0;//非 if(records==null) return 0; for(int i=0;i<records.size();i++) { int price=records.get(i).getPrice(); if(records.get(i).d.t)//若为特色菜 totala+=Math.round(price*acct); else totalb+=Math.round(price*acc); } return totala+totalb; } public Order(Menu menu){ this.menu = menu; } public Order() { } //根据菜名点菜 Record addARecord(int orderNum,String dishName,int portion,int num) { //不用判断菜品是否存在,main里会判断,在这里一定会存在 Record r = new Record(orderNum,menu.searthDish(dishName),portion,num); records.add(r); return r; } void delARecordByOrderNum(int orderNum){ //根据序号删除一条记录 for(int i=0;i<records.size();i++) { if(records.get(i).orderNum==orderNum) { records.remove(i); return ;//删除成功 } } System.out.println("delete error;");//删除失败 } } //桌子信息 class Table{ int table; Order order; int[][] tc = new int[3][2]; Table(int table,Order order) { this.order=order; this.table=table; } boolean addTC(String type,int du,int num){ if(type.equals("川菜")) { if(du>=0&&du<=5) { tc[0][0]+=du*num; tc[0][1]+=num; return true; } else System.out.println("spicy num out of range :"+du); } else if(type.equals("晋菜")) { if(du>=0&&du<=4) { tc[1][0]+=du*num; tc[1][1]+=num; return true; } else System.out.println("acidity num out of range :"+du); } else if(type.equals("浙菜")) { if(du>=0&&du<=3) { tc[2][0]+=du*num; tc[2][1]+=num; return true; } else System.out.println("sweetness num out of range :"+du); } return false; } } //客户信息 class Customer{ String name; String tel; int price; Customer(String name,String tel){ this.name=name; this.tel=tel; } int compareTo(Customer c) { return this.name.substring(0, 1).compareTo(c.name.substring(0, 1)); } void getTotalPrice(Table table) { price+=table.order.getTotalPrice2(); } @Override public String toString() { return name + " " + tel + " " + price; } }
这里给出一些比较复杂,比较难懂的代码的分析,代点菜功能在代码第64行,通过判断读入字符串的长度是否为5然后判断是不是代点菜,借着用已经保存好数据的p数组将数据解析出来然后就是正常流程,先查找有没有这个菜品,找到了就添加进订单,没找到就输出菜品不存在,然后看有没有重复点,删除前面的记录,最复杂的流程就是这个了,其他的一般流程也在这有所体现,这里看懂了就基本没什么问题了,然后是关于日期的判断,还是用字符串接收,用相应的方法再转为相应的日期,具体的看代码应该是能够看懂的,这里不难,这里值得一提的是ArrayList类,可以帮助我们高效简洁地解决需要数组的地方,关于Arraylist,其实就是数组的升级版,里面的成员需要是引用类型,语法在代码中就可以了解,具体可以查阅相关资料,我就不赘述了。
期中考试
第一题主要考察精度问题,题目也给出了提示,比较简单。
第二题换汤不换药,也是很简单的一题道题目。
第三题主要考察继承与多态,使用抽象类和抽象方法,并用子类继承且重写抽象方法。
第四题实现Comparable接口,以此对面积进行排序,前前后后已经接触这个数十次了,就不用多说了吧。
三、踩坑心得
1. 在java中很多关于区间的地方都是左闭右开,比如一个经典的例子:随机生成函数random,它能生成0~1间的一个数,且区间为[0,1)。
2. 小数精度的坑,这个在前面也多次提到了,double型不能精确的表示任何一个小数,在涉及高精度的计算时,需要用到BigDecimal类来帮助计算。
看看下图你会有更深的了解:
3. 还有就是我们在测试代码时经常出现运行超时,用快读可以帮助我们解决这个问题,比如题目集2中小明走格子这个题目就可以用到,因为它涉及到大量的输入,我们用的Scanner类效率较低不能在规定时间内运行出正确答案。
四、主要困难以及改进建议
1. 困难:不能清楚的抽象出类,思想还停留在上学期的面向过程编程。
建议:多加练习,抽象出类的思想需要大量的练习为基础,最终才能在脑海中形成一个类的世界。
2. 困难:对很多类比如哈希集太陌生,不知道在什么地方运用,从而使代码简洁高效。
建议:查阅相关资料同时通过刷题网站反复练习。
3. 建议:以后多用快读做到代码的高效性,摒弃Scanner类也是对代码对自己的一个提升。
4. 建议:多做注释,注释不仅仅是给别人看的,更是给自己看的。很有可能今天自己写的代码明天就忘记了,所以养成注释的良好习惯很重要。
五、总结
通过这三次题目集,我学到了String类及其使用方法比如:
int indexOf(int ch);//返回的是ch在字符串中第一次出现的位置
int indexOf(int ch, int fromIndex);//从fromIndex指定位置开始,获取ch在字符串中出现的位置
int indexOf(String str);//返回的是str在字符串中第一次出现的位置
int indexOf(String str, int fromIndex);//从fromIndex指定位置开始,获取str在字符串中出现的位置
int lastIndexOf(int ch);//返回的是str在字符串中最后一次出现的位置
boolean equals(str);等等
还有hashset类、ArrayList类、Calendar类、LocalDateTime类、BigDecimal类等。
对这些陌生类都需要进一步研究和学习,在代码熟练运用。
改进建议
最希望的就是每次pta作业结束后都能够讲解,不然同系列的题目最后只会拖的越来越多,不会还是不会,大大影响学习进度,还有就是实验结束后给出模范代码以供参考学习,这样才明白如何改进代码不至于停滞不前。最后就是实验、pta有时还有其他课程的任务等等叠在一周任务太紧,很难高效的完成作业,希望可以合理布置时间。