第二次博客
一、pta与期中总结
pta4和pta5是pta3的延申与拓展,菜单计价系统快写一个学期了,从开始的简单的点菜,简单的程序慢慢的迭代到现在,如果你对之前的几次pta作业完成的不错的话,那么pta4和pta5会比其他人更加的轻松。可是我前几次的pta作业做的不好,导致我这两次pta作业也都没有做好。在后面几次pta作业中我们对Java有了更深入的学习,在类的基础上我们还学习了父类的概念,还有接口。这些知识都可以在我们pta作业中使用,是我们的代码更加的简洁,明了。但是对于这些知识的使用有一定的难度,运用起来需要有一定的理解。
期中考试总体比较简单,可我对于接口不太熟练导致我在最后一题浪费了很多时间。一直在试错,一直在找错,这就是我对接口的不熟悉才导致的。
关于Java语法的问题
1、java语法有很多与c语言相通相似的地方,但是在具体细节上还是有些许的不同,也许这就是Java老师上课不讲前面的基础语法的原因。在这三次pta作业当中有很多错误都是因为自己对Java语法不太熟悉而导致的,这非常影响做题的熟读。不过这不算很大的问题,在以后多敲多写之后会对java语法有更多、更深的理解,在编写程序的时候会少浪费很多在语法上的时间。
2、小心使用运算符,第一次作业用==去比较两个BigInteger调了很久。
3、在pta4和pta5的作业中我经常遇到空指针的问题,我白天搞了很久还是没有搞懂为什么会这样,查资料也无济于事,让我十分崩溃。后面询问老师与同学才让我解决一些问题,但还是没有完全解决。我知道这些应该应该就是我代码的问题,可是时间已经不允许我仔仔细细的检查代码和修改了。
4、期中考试的题目总体比较简单,没有遇到什么语法上的问题。
关于题量
每次pta大作业的时间都是一个星期。题目数量不算多,但每次难度都在指数级上升,所以每次写作业的时间都在指数级上升。虽然pta4,和pta5都是在pta3上做迭代,而不是pta5在pta4上做迭代(要是pta5在pta4上面做迭代那么我一定还是写不出来)。
期中考试的题量不是很多,题目也不是很难。有一些人提前交卷就可以说明这个难度了。
pta4作业总结
这次作业是在前一次作业的基础上又增加了菜谱信息与订单信息混合等功能,虽然只有一题可是要实现程序还是有一定难度的。
代码实现
public class Main { public static void main(String[] args) { System.out.println("wrong format"); } class Dish { String name;//菜品名称 int unit_price; //单价 //int num; int getPrice(int portion) { int peic = 0; if (portion == 1) { peic = unit_price ; } else if (portion == 2) { peic = Math.round((float) (unit_price * 1.5)) ; } else if (portion == 3) { peic = (unit_price * 2) ; } return peic;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) } } class Menu { Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息 int count = 0; Dish searthDish(String dishName){ Dish temd = null; for(int i=count-1;i>=0;i--){ if(dishName.equals(dishs[i].name)){ temd = dishs[i]; break; } } if(temd==null){ System.out.println(dishName+" does not exist"); } return temd; }//根据菜名在菜谱中查找菜品信息,返回Dish对象。 Dish addDish(String dishName,int unit_price){ Dish dh = new Dish(); dh.name = dishName; dh.unit_price = unit_price; count++; return dh; }//添加一道菜品信息 } }
SourceMonitor上代码质量分析
输出结果:
因为这题我没有写出来所以没有输出结果
这题我写了很久把table order menu dish这些类都设计出来了可是我的主函数有大问题导致我一直报错,在我绞尽脑汁之后无奈选择了混分。用"wrong format混分可是后面也没有混成功
pta5作业总结
这次作业在pta3的基础上增加了特色菜:川菜,浙菜,晋菜。还有口味的选择。以及代点菜功能。要实现起来也有一定的难度。
这次作业是我做的最久的一次,我遇到的问题是我最麻烦困扰我最久的问题。程序在未运行时没有标红也就是没有语法错误,但是在运行时一直传出空指针错误
此次作业为点菜系统,需要实现对菜单的输出,以及对不同份额的菜品进行计算然后输出,以及对不合法情况的判断以及输出提示。在本题的题干给出了类的设计有部分的提示,但是由于我对类方法的不熟悉,没学明白所以此题还是没有做出来,唉。非常的不应该,原本我以为一个周末应该能做出来,但是我高估了我的水平,一个周末对于我来说压根做不出,只能提交编译都过不了的代码。
代码实现
import java.util.Calendar; import java.util.Scanner; import static java.lang.Integer.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); Menu mu = new Menu(); Table[] tables = new Table[10]; String[] a;//菜品输入 String[] b;//订单输入 StringBuffer str5 = new StringBuffer(); int a1; String st; int table_num = 0; int zhuo=0; while (true){//菜品的输入 st=in.nextLine(); a=st.split(" "); int count=a.length; if(st.equals("end"))break; if(a[0].equals("table")) { break; } if(count==2){//普通菜品的输入 if(!a[1].equals("delete"))mu.Add_Dish(a[0],null, Integer.parseInt(a[1]),false);continue; } if(count==4){//特色菜品的输入 if(a[3].equals("T"))mu.Add_Dish(a[0],a[1],Integer.parseInt(a[2]),true);continue; } } while (true){ if(zhuo!=0); st=in.nextLine(); b=st.split(" "); int c=b.length; if(b[0].equals("end"))break; if(c==7){ zhuo++; table_num= Integer.parseInt(b[1]); tables[table_num]=new Table(); tables[table_num].processDate(st); continue; } if(c==4){ if(!b[3].equals("T")){ if(tables[table_num]!=null) tables[table_num].order.addrecord(Integer.parseInt(b[0]),b[1],-1,Integer.parseInt(b[2]),Integer.parseInt(b[3])); }continue; } if(c==5){ if(tables[table_num]!=null) tables[table_num].order.addrecord(Integer.parseInt(b[0]),b[1],Integer.parseInt(b[2]),Integer.parseInt(b[3]),Integer.parseInt(b[4])); }continue; } for(int i=0;i<table_num;i++){ tables[i].Gettottalprice(); } } static class Dish{ String dish_name; String dish_kind;//记录是否是川菜这样的 int dish_basePrice;//菜品的基础价格 boolean is_tese; public Dish(){ } public Dish(String dish_name,String dish_kind,int dish_basePrice,boolean is_tese){ this.dish_name=dish_name; this.dish_kind=dish_kind; this.dish_basePrice=dish_basePrice; this.is_tese=is_tese; } int getPrice(int portion) { int peic = 0; if (portion == 1) { peic = dish_basePrice ; } else if (portion == 2) { peic = Math.round((float) (dish_basePrice * 1.5)) ; } else if (portion == 3) { peic = (dish_basePrice * 2) ; } return peic;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) } } static class Menu{ Dish[] dishes=new Dish[10]; int i=0;//记录是第几个菜单菜 public void Add_Dish(String dish_name,String dish_kind,int dish_basePrice,boolean is_tese){ dishes[i]=new Dish(dish_name,dish_kind,dish_basePrice,is_tese); i++; } public void Serch_Dish(String dish_name){ Dish serch_dish=null; Dish error_dish=null; for(int j=i-1;j>=0;j--){ if(dish_name.equals(dishes[j].dish_name)){ serch_dish=dishes[i]; } else { error_dish=dishes[j]; System.out.println(dishes[j]+"dose not exist"); } } // if(serch_dish==null){ // Dish error_dish=null; // error_dish=dishes[j]; // System.out.println("dose not exist"); // } } } static class Record{ int order_Num;//序号 Dish dh=new Dish(); int kouwei;//口味 int fene;//份额 int num;//数量 boolean is_zhengc=true;//判断这个订单是否正常 int total_price(){ return dh.getPrice(fene)*num; } } static class Order{ Record[] records = new Record[10];//保存订单上每一道的记录 int count=0; public void addrecord(int n,String name,int kouwei,int fene,int num){ if(records[count]!=null){ records[count].order_Num=n; records[count].dh.dish_name=name; records[count].kouwei=kouwei; records[count].fene=fene; records[count].num=num; count++;} } int Gettotal_price(){ int sum=0; for(int i=0;i<count;i++){ if(records[i].is_zhengc==true)sum=sum+records[i].total_price(); } return sum; } int[] Average_kouwei(){ int a_la=-1;//辣的平均 int a_suan=-1;//酸的平均 int a_tian=-1;//甜的平均 int la_jisuan=0,suan_jisuan=0,tian_jisuan=0; for(int i=0;i<=count;i++){ if(records[i].dh.dish_kind.equals("川菜")){ if(records[i].kouwei>5){ System.out.println("spicy num out of range : "+records[i].kouwei); records[i].is_zhengc=false; records[i].kouwei=0; } else{ a_la=a_la+records[i].kouwei; la_jisuan++; } } if(records[i].dh.dish_kind.equals("晋菜")){ if(records[i].kouwei>4){ System.out.println("acidity num out of range : "+records[i].kouwei); records[i].is_zhengc=false; records[i].kouwei=0; } else{ a_suan=a_suan+records[i].kouwei; suan_jisuan++; } } if(records[i].dh.dish_kind.equals("浙菜")){ if(records[i].kouwei>3){ System.out.println("sweetness num out of range : "+records[i].kouwei); records[i].is_zhengc=false; records[i].kouwei=0; } else{ a_tian=a_tian+records[i].kouwei; tian_jisuan++; } } } if(a_la!=-1) a_la=a_la/la_jisuan; if(a_suan!=-1) a_suan=a_suan/suan_jisuan; if(a_tian!=-1) a_tian=a_tian/tian_jisuan; int[] array={a_la,a_suan,a_tian}; return array; } public void Delete_Order(int i){ int x=0; for(int j=0;j<=count;j++){ if(i==records[j].order_Num) records[j].is_zhengc=false; x=1; } if(x==0) System.out.println("delete error;"); } } static class Table { int count=0;//几个人 float discnt; String date;//输入的字符串数据 int tableNum;//桌号 int sum=0;//一桌的总价 Human humans=new Human(); Order order=new Order(); boolean table_zhengc=true; int year,month,day,week,hh,mm,ss; void processDate(String date){//处理数据 table 2 : jerry 18100334566 2023/5/1 12/30/00 String[] temp = date.split(" "); //table 2 2022/12/3 15/03/02 tableNum = parseInt(temp[1]); humans.human_name=temp[3]; humans.phone_number=temp[4]; String[] temp1 = temp[5].split("/"); String[] temp2 = temp[6].split("/"); year = parseInt(temp1[0]); month = parseInt(temp1[1]); day = parseInt(temp1[2]); Calendar c = Calendar.getInstance(); c.set(year, (month-1), day); week = c.get(Calendar.DAY_OF_WEEK); if(week==1) week = 7; else week--; hh = parseInt(temp2[0]); mm = parseInt(temp2[1]); ss = parseInt(temp2[2]); if(week>=1&&week<=5) { if(hh>=17&&hh<20) discnt=0.8F; else if(hh==20&&mm<30) discnt=0.8F; else if(hh==20&&mm==30&&ss==0) discnt=0.8F; else if(hh>=11&&hh<=13||hh==10&&mm>=30) discnt=0.6F; else if(hh==14&&mm<30) discnt=0.6F; else if(hh==14&&mm==30&&ss==0) discnt=0.6F; } else if(week>5&&week<=7) { if(hh>=10&&hh<=20) discnt= 1.0F; else if(hh==9&&mm>=30) discnt= 1.0F; else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0) discnt= 1.0F; } else { System.out.println("table "+tableNum+" out of opening hours"); } } void Gettottalprice(){ if(discnt>0){ sum = Math.round(sum*discnt); System.out.println("table " + tableNum + ": " + sum); }else { System.out.println("table " + tableNum + " out of opening hours"); } } } static class Human{ String human_name; String phone_number; } }
在Source Monitor上代码质量分析结果:
结果分析:
从在Source Monitor上代码质量分析结果中可以看出整体代码复杂度不是很高,具有一定的可读性。从上图数据中也可以看出大部分数值都在正常范围内,没有很复杂的地方。
运行结果:
在我修改代码之后没有再传出空指针错误了而是没有结果输出。
期中考试总结
7-1
这题是要求我们写一个圆形类输出面积,十分简单直接秒杀
代码实现
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); double n=in.nextDouble(); Circle c1=new Circle(); c1.setRadius(n); //System.out.println(c1.jisuan(n)); if(c1.getRadius()>0){ System.out.println(String.format("%.2f",c1.jisuan(n))); } } static class Circle{ private double radius; double mianji; public void setRadius(double radius) { if(radius>0)this.radius = radius; else System.out.println("Wrong Format"); } public double getRadius() { return radius; } public Circle(){ } public Circle(double n){ radius=n; } public double jisuan(double r){ mianji=Math.PI*r*r; return mianji; } } }
在Source Monitor上代码质量分析结果:
结果分析:
这题是期中考试最简单的一题
7-3
本体结合了前两题的类的设计,综合了前两题,要在其中设计父类。,Circle及Rectangle作为子类。
代码实现:
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); int choice = input.nextInt(); switch(choice) { case 1://Circle double radiums = input.nextDouble(); if(radiums>0){ double s=Math.PI*radiums*radiums; System.out.println(String.format("%.2f",s)); break; } 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(); double s1; s1=Math.abs((x1-x2)*(y1-y2)); System.out.println(String.format("%.2f",s1)); } } }
由上图可知,各方法的结构化程度和循环复杂度较低,方法间的耦合度较低,类的循环复杂度也较低。并且各方法的规模,控制分支数目以及类总代码规模也都不大。因此,设计架构还是比较清晰的。
但是没有使用到父类非常不好,虽然测试点过了但这是投机取巧的办法十分不可取。
7-4
这题在7-3的基础上又增加了一些东西:重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)而且可以判断多组数据从而输出不同图像的面积。在输出的时候还要按照其面积大小来判断输出顺序。
不过这题有题解可以帮助我们类的设计与接口的设计
-
实现Comparable接口
-
接口中的方法为int compareTo(Shape);
代码实现:
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); int choice = input.nextInt(); double[] a=new double[1000]; int count=0; while (choice!=0){ switch(choice) { case 1://Circle double radiums = input.nextDouble(); if(radiums>0){ double s=Math.PI*radiums*radiums; a[count]=s; count++; // System.out.println(String.format("%.2f",s)); choice=input.nextInt(); break; } System.out.print("Wrong Format"); break; case 2://Rectangle double x1 = input.nextDouble(); double y1 = input.nextDouble(); double x2 = input.nextDouble(); double y2 = input.nextDouble(); double s1; a[count]=Math.abs(x1-x2)*Math.abs(y1-y2);; choice=input.nextInt(); count++;break; // System.out.println(String.format("%.2f",s1)); } } for(int i=0;i<count;i++){ for(int j=i;j<count;j++){ if(a[i]>a[j]){ double x=0.0; x=a[i]; a[i]=a[j]; a[j]=x; } } if(a[i]>-1)System.out.print(String.format("%.2f",a[i])+" "); } } }
在Source Monitor上代码质量分析结果:
从上图可知代码复杂度不高,代码比较简洁。
三、踩坑心得
在一部分题目中因为代码复杂程度高,修改起来十分麻烦,全删重写时间又不够,只能在原先的代码上进行修修补补,但是这种修修补补的效果不尽如人意。尤其是在pta5的作业当中,我知道我的代码有很大问题,可是时间一斤不允许我从新在写一次,只能在原先的代码中修修补补。
四、主要困难以及改进建议:
1、学习更多的关于数据结构的算法和语法,在实际的Java开发当中有许多可以直接利用的数据结构以及先进的算法,这些都可以直接拿过来使用,可以降低程序的复杂程度,节省自己的时间去优化自己的代码。使Java编程更加有效。
2、持续练习是非常有必要的,编程的难度不仅仅在于对语法的熟练掌握,还需要不断联系才能更好的理解更好的融汇贯通与应用它们。所以在Java语言的学习中应该尽可能的多写多敲多看代码,因为这样才能提高自己的编程水平让自己得到提高。
五、总结
在这两次pta作业和期中考试中我深刻的体会到:学习编程语言是非常需要有一个强的执行能力,不能偷懒不能懈怠。从事程序员这一工作就要做好终身学习的觉悟。自学能力也是一个非常重要的素质。
总结这几次作业,我掌握了Java程序设计的核心该奶奶,包括变量,数据类型,运算符,语句条件,循环条件,数组,字符数组,以及方法的使用。虽然没有掌握对类的使用但我相信在以后的java学习中我一定熟练掌握的。
此外我还学会了如何使用一些常见编译器的进行Java开发如:Eclipse,lightly等。我还注意到编写Java程序时需要遵循一些最佳实践和约定,例如类/方法/变量名要有意义、注释要详尽、避免使用魔法数、异常处理要规范等等。总之,通过Java作业的练习,我获得了更加全面的Java知识体系和实践能力,锻炼了思维方式,也使java的面向对象的编程方式变得更加熟练。