这三次菜单分析主要考察学生对于面对对象程序设计的理解,不同以往的是我们之前是面向过程,这毫无疑问会增加代码的复杂程度,而这次菜单计价系统则是主要考察我们面对对象程序设计能力,要求我们运用封装对象,对象之间的联系,类的调用和类的相互之间调用,总而言之,相对于c来说 java的主函数内容更少一点,关系逻辑更多一点,注重对象。而c则是面向过程多一点。
首先来说第一次作业:
#代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String a; Menu p = new Menu(); Order l = new Order(); int count = 0; while (true) { a = in.nextLine(); if (a.equals("end")) break; String[] b = a.split(" "); l.records[count] = new Record(); l.records[count] = l.addARecord(b[0], Integer.parseInt(b[1])); count++; } Dish q; for (int i = 0; i < count; i++) { q = p.searthDish(l.records[i].d.name); if (q == null) { System.out.println(l.records[i].d.name + " does not exist"); } else { l.records[i].d.unit_price=q.unit_price; } } System.out.println(l.getTotalPrice()); } } class Dish { String name; int unit_price; int getPrice(int portion) { if (portion == 1) { return ((int) (Math.round(unit_price * 1.0))); } if (portion == 2) { return ((int) (Math.round(unit_price * 1.5))); } if (portion == 3) { return ((int) (Math.round(unit_price * 2.0))); } return 0; } } class Menu { Dish[] m=new Dish[4]; Dish searthDish(String dishName) { m[0]=new Dish(); m[1]=new Dish(); m[2]=new Dish(); m[3]=new Dish(); m[0].name="西红柿炒蛋"; m[1].name="清炒土豆丝"; m[2].name="麻婆豆腐"; m[3].name="油淋生菜"; m[0].unit_price=15; m[1].unit_price=12; m[2].unit_price=12; m[3].unit_price=9; for(int i=0;i<4;i++) { if(dishName.equals(m[i].name)) { return m[i]; } } return null; } } class Record { Dish d=new Dish(); int portion; int getPrice() { return d.getPrice(portion); } } class Order { Record[] records=new Record[50000]; int sum=0; int i1; int getTotalPrice() { for(int i=0;i<i1;i++) { sum=sum+records[i].getPrice(); } return sum; } Record addARecord(String dishName,int portion) { Record o=new Record(); o.d.name=dishName; o.portion = portion; i1++; return o; } }
首先来说第一题的知识点,就是简单的对象调用,理清楚对象之间的关系,明白对象之间的作用与调用,譬如,每一个订单的获取价格和总的获取价格。总的获取价格就是每个订单的获取。更加重点调查了split(),equals()只能用于字符串的对比。Math.round()函数的四舍五入,类型转换的强制类型转换(如果不加会报错,给出数据损失的错误),调用对象的方法时候要先创建对象,一定要NEW一个出来,不然没有空间。
它的题量相对于菜单-2和菜单-3来说少很多,但是相对于刚入门java的同学来说难度很大,主要是思想的转变会让一些同学不太适应。初来乍到的java学习者可能会花费大量的时间来改变之前的思想。
同时难度相对于菜单-2和菜单-3来说也简单很多,是菜单-2和菜单-3的前提基础,前提机要。
首先主函数Main()其中含有Menu Dish Record Order等类,然后Menu里面又DIsh 因为菜单一定会有菜,有菜的元素,比如菜名,菜价等。Record里面有Dish 。而Order里一定会会有Record,又因为Record里面含有Dish,所以Order也就有Dish了,这时候各种类之间的关系已经显而易见。就可以开始编写类里面的方法了。当时一定会很懵,因为毕竟是初学者,一时间不了解java的编程方法。这是需要我们细细去摸索的,写出来第一个程序后面就好说了。
当然我也遇到了很多问题,其中比如一开始没有四舍五入,数据损失,没有查到dish,类里的变量不能从主函数中获取等。但是这些都是一些简单的问题可以通过调试来解决。相比于菜单-2和菜单-3我遇到的问腿少多了。
代码也有很多问题,比如时间复杂度高,没有考虑输入错误的情况等。
菜单-2
#代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String a; int []c=new int[10000]; Menu p = new Menu(); Order l = new Order(); Order rt = new Order(); int count = 0; int flag = 0; int con=0; int flag1=0; int count1=0; int rw=0; int []a1=new int [10000]; int r= l.getTotalPrice(); while (true) { a = in.nextLine(); if (a.equals("end")) break; String[] b = a.split(" "); if(b[0].length()>=3) { p.m[count1]=p.addDish(b[0],Integer.parseInt(b[1])); count1++; } if((b[0].length()<3)&&!b[1].equals("delete")) { if(count<count1) { l.records[count] = new Record(); l.records[count] = l.addARecord(Integer.parseInt(b[0]), b[1], Integer.parseInt(b[2]), Integer.parseInt(b[3])); count++; } else { rt.records[rw]=new Record(); rt.records[rw]=rt.addARecord(Integer.parseInt(b[0]), b[1], Integer.parseInt(b[2]),Integer.parseInt(b[3])); rw++; } } if(b[1].equals("delete")) { int k =Integer.parseInt(b[0]); flag++; if(k<=flag) {a1[flag1]=k; flag1++;} else { con++; } } } Dish q; for (int i = 0; i < count; i++) { q = p.searthDish(l.records[i].d.name); if (q != null) { l.records[i].d.unit_price=q.unit_price; System.out.println(i+1+" "+l.records[i].d.name+" "+l.records[i].getPrice()); } } Dish y; for(int i = 0; i<rw;i++) { y = p.searthDish(rt.records[i].d.name); if (y == null) { System.out.println(rt.records[i].d.name + " does not exist"); } } for(int i=0;i<con;i++) { System.out.println("delete error;"); } int r1; r1= l.getTotalPrice(); if(flag1!=0) for(int i = 0 ;i<=flag1;i++) { if (a1[i] < count - 1) r1 = r1 - l.records[a1[i]].getPrice(); } System.out.println(r1); } } class Dish { String name; int unit_price; int getPrice(int portion) { if (portion == 1) { return ((int) (Math.round(unit_price * 1.0))); } if (portion == 2) { return ((int) (Math.round(unit_price * 1.5))); } if (portion == 3) { return ((int) (Math.round(unit_price * 2.0))); } return 0; } } class Menu { Dish[] m=new Dish[10000]; int count=0; Dish searthDish(String dishName) { for(int i=0;i<count;i++) { if(dishName.equals(m[i].name)) { return m[i]; } } return null; } Dish addDish(String dishName,int unit_price) { Dish s = new Dish(); s.name=dishName; s.unit_price=unit_price; count++; return s; } } class Record { Dish d=new Dish(); int portion; int fen; int xu; int getPrice() { return fen*d.getPrice(portion); } } class Order { Record[] records=new Record[50000]; int sum=0; int i1; int getTotalPrice() { for(int i=0;i<i1;i++) { sum=sum+records[i].getPrice(); } return sum; } Record addARecord(int xu,String dishName,int portion,int fen) { Record o=new Record(); o.d.name=dishName; o.portion = portion; o.fen=fen; o.xu=xu; i1++; return o; } }
相对于第一次作业,第二次作业代码量明显变多了,也明显复杂了,因为考虑到删除和增加菜单信息,所以相对于第一题代码量变多。
第二题的知识点更多围绕存储和调用,什么是存储,即数据的读入,比如如何确定要将你读到的东西放进去,如何将你边读边写的时候分辨出那里是要进菜单的,那里是不要的。
这里用到了length和length()的区别和split的巧用,length是字符数组的长度,而length()是字符串的长度。
巧用length和length()来解决那些进入菜单的问题,同时难度相对于菜单-1来说难很多,是菜单-1的延申,扩展。
这一题我没有拿到满分,主要是因为
1------审题错误,由于我直接将第一题的代码复制过来进行修改,没有审清楚题目,导致我菜单还以为是固定的,其实菜单是自己添加的。
2------时间不充足,由于我总想着半天解决,其实代码不是能够一时间就可以做出来的东西,一定要给足时间,否则忙里来写,就会出很多BUG,会越写越乱。
首先主函数Main()其中含有Menu Dish Record Order等类,然后Menu里面又DIsh 因为菜单一定会有菜,有菜的元素,比如菜名,菜价等。Record里面有Dish 。而Order里一定会会有Record,又因为Record里面含有Dish,所以Order也就有Dish了,这时候各种类之间的关系已经显而易见,我在Dish里面添加了getprice在Munu里面添加了adddish和searthdish,adddish的作用是将开始输入的菜名以及价格存入数组Dish中,searthdish则是在查找订单中是否出现了菜单里未拥有的菜品,进而输出not exist。还可以再创一个删除(这里我没创建因为审题错误)当查找到序号存在且菜品拥有的时候可以return回来负的;而没有return 0回来 如果是0则输出delete error。
这样子就可以用gettotalprice去计算价格。
同时这个我也遇到了很多问题,比如当时不知道如何确定输出的顺序 我采用了各种计数器来实现,比如delete过后实际价格不对应,我发现有重复计算等,还有数组越界等问题,通过调试一一发现,同时这个代码我也没有考虑输入出错的情况。
菜单-3
#代码如下:
import java.time.DayOfWeek; import java.time.LocalDate; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String a; int[] c = new int[10000]; Menu p = new Menu(); Order l = new Order(); Order rt = new Order(); table [] t=new table[1000]; Dish q; int count = 0; int flag = 0; int con = 0; int flag1 = 0; int count1 = 0; int rw = 0; int[] a1 = new int[10000]; while (true) { a = in.nextLine(); if (a.equals("end")) break; String[] b = a.split(" "); if (b.length == 2 && !b[1].equals("delete")) { p.m[rw] = p.addDish(b[0], Integer.parseInt(b[1])); rw++; } // Dish q; // for (int i = 0; i < count; i++) { // q = p.searthDish(l.records[i].d.name); // if (q == null) // System.out.println(l.records[i].d.name + " does not exist"); if(b[0].equals("table")) { flag1=Integer.parseInt(b[1]); count++; con=0; } if(b.length==4&&a.length()<11) { t[flag1]=new table(); t[flag1].x1.records[con]= rt.addARecord(Integer.parseInt(b[0]), b[1], Integer.parseInt(b[2]),Integer.parseInt(b[3])); t[flag1].x1.ci++; t[flag1].jiage+=t[flag1].x1.records[con].getPrice(); con++; } if(b[1].equals("delete")) { if(t[flag1].x1.delARecordByOrderNum(Integer.parseInt(b[0]))==0) t[flag1].x1.check++; t[flag1].jiage-=t[flag1].x1.delARecordByOrderNum(Integer.parseInt(b[0])); } } for(int i=1;i<=count;i++) { System.out.println("table "+i+":"); for(int j=1;j<t[i].x1.ci;j++) { System.out.println(j+1+" "+t[i].x1.records[j].d.name+" "+t[i].x1.records[i].getPrice()); } for (int sss = 0; sss < rw; sss++) { q = p.searthDish(t[i].x1.records[i].d.name); if (q == null) System.out.println(t[i].x1.records[i].d.name + " does not exist");} for(int iq=0;iq<t[i].x1.check;i++) { System.out.println("delete error;"); } } for(int i=1;i<=count;i++) { System.out.println("table "+i+": "+t[i].jiage); } } } class Dish { String name; int unit_price; int getPrice(int portion) { if (portion == 1) { return ((int) (Math.round(unit_price * 1.0))); } if (portion == 2) { return ((int) (Math.round(unit_price * 1.5))); } if (portion == 3) { return ((int) (Math.round(unit_price * 2.0))); } return 0; } } class Menu { Dish[] m=new Dish[10000]; int count=0; Dish searthDish(String dishName) { for(int i=0;i<count;i++) { if(dishName.equals(m[i].name)) { return m[i]; } } return null; } Dish addDish(String dishName,int unit_price) { Dish s = new Dish(); s.name=dishName; s.unit_price=unit_price; count++; return s; } } class Record { Dish d=new Dish(); int portion; int fen; int xu; int getPrice() { return fen*d.getPrice(portion); } } class Order { Record[] records=new Record[50000]; int sum=0; int i1; int check=0; int ci=0; int getTotalPrice() { for(int i=0;i<i1;i++) { sum=sum+records[i].getPrice(); } return sum; } Record addARecord(int xu,String dishName,int portion,int fen) { Record o=new Record(); o.d.name=dishName; o.portion = portion; o.fen=fen; o.xu=xu; i1++; return o; } int delARecordByOrderNum(int orderNum) { if(findRecordByNum(orderNum)==true) { sum=0-records[orderNum].getPrice(); return sum; } else return 0; } boolean findRecordByNum(int orderNum) { for(int i=0;i<i1;i++) { if(orderNum==i) return true; } return false; } } class table { int tablenumber; int nian; int yue; int ri; int shi; int fen; int miao; int jiage=0; Order x1 = new Order(); }
相对于第一次作业和第二次作业代码量明显变多了,也明显复杂了,因为考虑到代点餐和桌子类和时间折扣信息,所以相对于第二题代码量变多很多。
第三题的知识点更多围绕如何创建新的类和新的类调用什么类,一些时间函数的运用,比如如何确定这个时间点是周几,这个时间在周几的那个时间段,是几折,还是未营业,如何将你边读边写的时候分辨出那里是要进菜单的,那些是要读到时间的,那些是统计不同桌子的价格的(即table的Gettotalprice)。
这里用到了length和length()的区别和split的巧用,length是字符数组的长度,而length()是字符串的长度。
巧用length和length()来解决那些确定菜单,确定时间,确定哪里是哪个桌子的点餐的问题,同时难度相对于菜单-2来说难很多,是菜单-2的延申,扩展。
这一题我没有拿到分,主要是因为
1------数组越界不知道如何处理,有一些数据存不进去,找不到哪里出现了问题。
2------table的价格统计没有存入数据,发现最后输出一直是0。
3------时间不知道如何处理,虽然知道是周几,但是不知道如何确实时分秒是否在规定时间内。
4------代点餐方面,不知道如何用订单的价格加入上一桌子的gettotalprice里面去。
首先主函数Main()其中含有Menu Dish Record Order等类,然后Menu里面又DIsh 因为菜单一定会有菜,有菜的元素,比如菜名,菜价等。Record里面有Dish 。而Order里一定会会有Record,又因为Record里面含有Dish,所以Order也就有Dish了,我还增加了一个table类,table里面包含订单order即一个table统计order的价格(gettotalprice),在读到table后将菜加入到table的order中,对table[i]里的order进行操作。
同时这个我也遇到了很多问题,比如当时依旧不知道如何确定输出的顺序 我采用了各种计数器来实现,比如我发现有价格存不进去等,还有数组越界等问题但是没有解决掉,同时这个代码我也没有考虑输入出错的情况,也没写入时间的判断。
#以上是每个菜单的分析,接下来是总体总结:
首先我每一个代码都没有考虑到时间复杂度,没有考虑时间效率。
其次我发现我对java类的理解还是不够深刻,前些日子讲的组合,关联,聚集等受益匪浅。
等下一次pta大作业,一定要提前留出充足的时间,不能到最后的时候去赶作业。
上课多注意老师的纠出来的易错点,都可能是我们会出现的。
课下多研究java的编写方式,编程思想。