关于三次pta大作业的总结报告
Posted buai-xieddaima
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于三次pta大作业的总结报告相关的知识,希望对你有一定的参考价值。
关于三次大作业的总结
一.前言(主要总结三次题目集的知识点,题量,难度及其他)
1>.关于第一次大作业:
整体而言,第一次大作业确实是开胃菜,与其说面向对象,不如说面向过程,但是万万没想到这是噩梦的开始,废话少说,开始逐个分析吧。
第一题:“身体质量指数”,难度(个人感觉):简单
整个逻辑就是if-else语句,在各种情况下计算出BMI指数,根据BMI所在范围判断身体状况,非要说这题的重点的话,那就是用来了解java语言的基本基本语法,掌握输入输出即可,知识点考察的话就是基本的读题能力,判断用户到底需要什么功能,读懂就可以;
第二题:“长度质量计量单位换算”,难度:简单
题目大致就是输入浮点数重量 千克为单位和浮点数和浮点数长度 米为单位,输出相对应的以磅为单位的质量和以英寸为单位的长度,唯一需要注意的就是输出的结果,用float强制转换一下,原定义的变量为double型,运算得到的本应该也是double型的,但是出题人(..)却偷偷做了手脚,我猜是特意限制了输出类型为float型,实在是高(我是最后试出来的),其他没什么照着输入输出给出计算公式即可;
第三题:“奇数求和” 难度:简单
同样是简单的知识点,判定一个数是否为奇数,众所周知,对2取余即可,如果得到余数不等于0则是奇数,反之;题目是对奇数求和,定义一个整型变量sum将奇数加到变量上就好了,题目而且是直接说明是输入十个数,更是手下留情,生怕我看不懂题,属于是太贴心了(原来狠的在后面),所以本题也没什么注意的,按部就班就好,最后输出sum;
第四题:“房产税费计算2022” 难度:简单+
说实话前几次下手提交,多多少少都有些小问题,题目也是比较接近现实,属于每个人都会有的事,题目要求输入四个数据,第几次购房(整数),房款(整数),评估价(整数),房屋面积(浮点数),且在一行输入,结果需要计算出契税,印花税,交易费,测绘费,空格分割,逻辑与前几题一样,按给出公式计算即可,不过问题也就是出自这里,根据题目意思,契税是和购房次数有关系的,前几次的写法是不效率的,重复去if-else语句嵌套,其实是不用的,因为会发现其他三个费用是固定的,只要找到契税的关系即可,稍微花了点时间,可以看出自身对于实际问题的考虑还是不成熟的,还要多想多面对;
第五题:“游戏角色选择” 难度:简单
算是比较接近我们男生的题目了(男人的浪漫),进入游戏的角色选择,选择不同的种族,不同的种族相对应不同的角色,根据不同的情况给出相应的输出就行,我的解决方法是switch语句来解决,但是现在看来这样写的语句复杂度还是高了点,而且用的是switch的嵌套语句,不过能解决问题,目前来说,我也确实想不到更好的方法解决了;
第六题:“学号识别” 难度:中
这道题算是当时写的重头戏了,难住了有些点时间,回顾自己写的代码,属于是有点是落时代了,先分析分析题目吧,题目要求对输入的学号进行信息读取,南航本校学号8位,8位学号的前两位为入学年份,34位代表学院,56为代表班级,最后两位代表班级学号,对于学号的输入要给出以上信息,我给出的解法是:对输入的整型数据学号进行分解,每两位分解,原始方法了,分解完后赋值给a,b,c,d四个变量,然后再去判断,那时候对字符串的了解还不足,甚至一点不了解,其实现在想想,只要用String类的chatAt方法,就能轻松提取出学号内的各位,再去判断就好,当时来说,这道题的知识点确实学到了,利用类方法解决,顺便带一句,本题还有错误输出的判定,不过问题不大;
第七题:“巴比伦法求平方根近似值” 难度:简单++
属于数学问题了,去猜测一个数的开根号大概是多少,逻辑大概就是:nextGuess = (lastGuess+n/lastGuess)/2
程序初始运行时lastGuess可赋予一个最初的猜测值。当由公式求得的nextGuess和lastGuess相差较大时,把nextGuess的值赋给lastGuess,继续以上过程,直至nextGuess和lastGuess几乎相同,此时lastGuess或者nextGuess就是平方根的近似值,再对lastGuess输入加上判定即可,输入为浮点型,本题也是考察读题能力;
第八题:“二进制数值提取” 难度:中
本题要求对输入的字符串提取出里面的0 1,其他不管,思路也很清晰,利用一个空字符串,将提取出来的0和1加入其中即可,循环识别,当识别到\'-\',并且下一个为\'1\'时,说明识别结束返回程序,本题学到的知识点我觉得说那个字符串竟然是可以直接相加的,相加结果就是拼接,这是当时也不知道的;
第九题:“判断三角形类型” 难度:中 -
这道题虽然放在最后一题,但是却是我比较早做完的一道题,主要因为逻辑很清晰,只要对三角型的满足条件做判断,什么条件对应什么类型三角形即可,也没什么注意的点;
综上,第一次大作业总体确实是开胃菜,真的还在后面,总体难度肯定是简单的,题量来说,将近十题,本来是挺多的,但是在简单的前提下,其实不多,就是写分析挺够写的(小小吐槽一下)。
2>关于第二次大作业:
第二次大作业相比较下,就动真格的了,真正的面向对象现在才开始,做完这次大作业真的对于面向对象的概念逐渐清晰了一点,体会到在大一点的程序面前,类的封装使用,更好能解决问题,这是面向过程所解决不了的。这次重点就分析前两题吧。
第一题:“菜单计价程序-1” 难度:难
我觉得重点难在类的设计上以及类之间的调用关系,在开始拿到这道题的时候是一脸懵逼,要说思路的话,有一点但是不多,我一直不能理解的问题就是他们不同的类是怎么一起分工,一起解决这件事的,经过几天的理解,以及向同学询问,慢慢了解,整体主要分为两大类,一个菜谱类,另一个订单类,菜谱里是包含菜品这一类的,订单类里是包括记录这类的,要在简单点说的话,菜谱顾名思义就是有一个个的菜品构成的,我理解的是一个被包含的关系,而订单同样是由一个个的订单构成的,客户每点一个菜,一次记录,就记录在记录类中,可大致关系明了后,依旧还是问题重重,后面在分析部分详细分析;
第二题:“菜单计价程序-2” 难度:难+
这一题在第一题的基础上加了查找订单,删除订单的概念,即客户可以删除已点菜的信息,包括对点菜记录的删除,价格的不再计算,查找订单实际上就是为删除订单服务的方法,还有对于没有该订单的记录,会显示删除失败的信息,实则就是利用查找序号的功能查询,最后同样输出总价格,所以对删除价格的处理,我是将要删除的订单的价格加在另外一个数组中,然后减去这个和,就是最后的总价格,以上就是我对第二题新增的内容的理解了,很遗憾没有完成全部测试点;
第三题:“jmu-java-日期类的基本使用” 难度:难-
这道题其实由于时间原因,并没有写,只是大概看了题目意思,考察对java时间类的使用,属于新一点的知识点了,那我就大概说说现在来看的理解吧,java中自带的时间类有好几种的,LocalDate类算是比较好用的了,可以提取出一个时间的年月日,并且还有判断先后的方法,是比较方便了,没有实际完成,就不好纸上谈兵了,想想后续还是要补上;
第四题:“小明走格子” 难度:难++
在搜索相关知识后,才明白这是一个有关动态规划的问题,也是递归的使用,说实话没有查相关知识的话,以我的递归水平,我绝对是写不出来的,还有Scanner输入的优化,使用nextToken加快输入而不超时;
综上第二次大作业,题量很大,难度对我来所也挺大的,虽然只有四个题目,但是每个题目都是新的挑战,新的知识点,要学的东西还有很多,特别是点菜程序,还是慢慢爬吧,好难啊...
3>关于第三次大作业:
第一题:“菜单计价程序-3”
关于这道题,没有写完,就说说丁点理解吧,新增了table类的概念,因此肯定要新建table的属性和方法,客户点餐还包括桌号,还有帮桌点菜的功能,但是价格算在自己的桌号上,还有时间的概念,在不同的时间内,会有不同的折扣以及不营业,需要加上这些功能;判定table的思路应该是当读到“table”的时候,将后面的时间提取出来,然后对比营业时间给出相应的折扣。
第二题:“有重复的数据” 难度:中
本题有对新的知识点的学习,就是数据结构的一种哈希表,哈希表自带的一种功能就是可以实现除重的功能,可以将数据放入哈希表中,然后储存的数据就会排除掉重复的数据,因此本题只需要将数据放入哈希表,然后判断哈希表的大小是否等于数据个数,如果相等,那就说明没有重复的数据了,反之;
第三题:“去掉重复的数据” 难度:中+
这题与上一题有差不多的思路,也是利用哈希表对数据进行排重,不同的是用了Hashset类的一个contains方法,原理是在哈希表中查询是否有同样的数,那么这题的思路就是输入一个数,然后对这个数进行判断。如果哈希表中没有这个数,就输出这个数,然后写入哈希表中,当全部输入完毕后,整个功能也就实现了,需要注意的是这题要考虑输出的格式要求,在输出最后一个数的时候在前面加上空格即可;
第四题:“ 单词统计与排序” 难度:中++
同样是延续了上一题的知识点,哈希表的使用,但是不是重点,重点是对一句话的分割,以及排序的实现,题目要求对一句话按每个单词的长度顺序每行输出,如果长度相等,则按首字母字母表顺序输出,我的排序办法是,首先利用选择排序法将每个单词长度排序,然后再用String类的比较方法compareToIgnoreCase忽略大小写进行再次排序然后存在数组中,最后用哈希表的排重,将单词数组除去相同的单词,最后输出数组即可;
第五题:“面向对象编程(封装性)” 难度:中-
这题是对面向对象封装性的一个理解,我觉得问题不大,不做过多解释了;
第六题:“GPS测绘中度分秒转换” 难度:简单+++
反观这一题有一点第一题的意味了,与本次大作业有点小反差,题目给出了计算方法,也给出了输入输出格式,测试点明显,唯一需要的注意的是最后输出的秒的格式,题目说的只是有小数,但是并没有说一定是几位小数,因此采用%.f格式输出是行不通的,我用的%s格式输出,这样的就巧妙避免了这个问题;
第七题:“ 判断两个日期的先后,计算间隔天数、周数” 难度:中+
本题我用的时间类是Date类,利用相差的毫秒数计算哪个日期更早,以及相差的天数,周数;
综上,本次大作业的题量如果除去第一题的话算是中规中矩的,难度也是中规中矩,但是加上第一题简直是不知如何形容,这次大作业的前一次都没有完全实现,我实在想不明白接下来的咋做呢,啊啊啊啊....
二.设计与分析:
主要针对部分题目分析:
第二次大作业第一题
我的代码实现:
import java.util.Scanner; public class Main public static void main(String[] args) Scanner input = new Scanner(System.in); //初始化Dish类数组 Dish[] dishs_ = new Dish[10]; Menu menu = new Menu(); dishs_[0] = new Dish(); dishs_[1] = new Dish(); dishs_[2] = new Dish(); dishs_[3] = new Dish(); dishs_[0].name="西红柿炒蛋"; dishs_[0].unit_price=15; dishs_[1].name="清炒土豆丝"; dishs_[1].unit_price=12; dishs_[2].name="麻婆豆腐"; dishs_[2].unit_price=12; dishs_[3].name="油淋生菜"; dishs_[3].unit_price=9; //将dishs_数组存入menu类中 menu.dishs = dishs_; Order order = new Order(); //记录每次点菜的records_数组 //Record[] records_ = new Record[100]; int dish_portion; int[] oneprice = new int[10]; int totalPrice=0; int i = 0; while(true) String dish_name=input.next(); //records_[i].d.name=dish_name; if(dish_name.equals("end")) break; //在menu中查找是否有此菜品 //Dish[] notdish = new Dish[10]; if(menu.searthDish(dish_name)==null) dish_portion=input.nextInt(); System.out.println(dish_name+" does not exist"); else //继续输入菜品的份额存入records dish_portion=input.nextInt(); //records_[i].d.unit_price=dish_portion; order.records[i] = order.addARecord(dish_name,dish_portion); order.records[i].d = menu.searthDish(dish_name); //计算单个点菜的价格并加入总价 oneprice[i] = order.records[i].getPrice(); totalPrice+=oneprice[i]; i++; //totalPrice = order.getTotalPrice(); System.out.print(totalPrice); //菜品类:对应菜谱上一道菜的信息。 class Dish String name;//菜品名称 int unit_price; //单价 //菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 class Menu Dish[] dishs = new Dish[10] ;//菜品数组,保存所有菜品信息 public Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 //Dish[] notdish = new Dish[10]; int i; for(i=0;i<=3;i++) if(dishName.equals(dishs[i].name)) return dishs[i]; return null; //点菜记录类:保存订单上的一道菜品记录 class Record Dish d = new Dish();//菜品 int portion;//份额(1/2/3代表小/中/大份) public int getPrice()//计价,计算本条记录的价格 int onePrice = 0; if(d.name.equals("西红柿炒蛋")) if(portion == 1) // portion onePrice=d.unit_price; if(portion==2) //四舍五入 onePrice= (int)Math.round(d.unit_price * 1.5); if(portion==3) onePrice = d.unit_price * 2; if(d.name.equals("清炒土豆丝")) if(portion==1) onePrice=d.unit_price; if(portion==2) //四舍五入 onePrice=(int)Math.round(d.unit_price * 1.5); if(portion==3) onePrice=d.unit_price*2; if(d.name.equals("麻婆豆腐")) if(portion==1) onePrice=d.unit_price; if(portion==2) //四舍五入 onePrice=(int)Math.round(d.unit_price * 1.5); if(portion==3) onePrice=d.unit_price*2; if(d.name.equals("油淋生菜")) if(portion==1) onePrice=d.unit_price; if(portion==2) //四舍五入 onePrice=(int)Math.round(d.unit_price * 1.5); if(portion==3) onePrice=d.unit_price*2; return onePrice; //订单类:保存用户点的所有菜的信息。 class Order Record[] records = new Record[100];//保存订单上每一道的记录 // public int getTotalPrice()//计算订单的总价 // Record record2 = new Record(); // int allPrice; // for() // public Record addARecord(String dishName,int portion)//添加一条菜品信息到订单中。 Record record1 = new Record(); record1.d.name=dishName; record1.portion =portion; return record1;
我的类图:
SourceMonitor上代码质量分析结果:
第二次大作业第二题:
代码只实现了部分功能:
import java.util.Scanner; public class Main public static void main(String[] args) Scanner sc = new Scanner(System.in); Menu menu = new Menu(); Dish[] dishs_ = new Dish[20]; dishs_[0] =new Dish(); dishs_[1] =new Dish(); //输入菜单信息 String dish_name1= sc.next(); int dish_unit_price1 = sc.nextInt(); String dish_name2= sc.next(); int dish_unit_price2 = sc.nextInt(); dishs_[0].name = dish_name1; dishs_[0].unit_price = dish_unit_price1; dishs_[1].name = dish_name2; dishs_[1].unit_price = dish_unit_price2; //存入menu中 menu.dishs = dishs_; //添加菜品信息 // menu.dishs[0] = menu.addDish(dishs_[0].name,dishs_[0].unit_price); // menu.dishs[1] = menu.addDish(dishs_[0].name,dishs_[0].unit_price); //数据测试部分 // System.out.print(menu.dishs[1].name); // System.out.println(menu.dishs[1].unit_price); Order order = new Order(); int i=0,totalPrice=0; int order_Dish_portion; int order_Dish_Num; int[] onePrice = new int[10]; int[] deletePrice = new int[10]; while(true) String order_Dish_num = sc.next(); //序号输入 //判断菜谱中是否存在 if (order_Dish_num.equals("end")) break; //在菜谱中查找 else String order_Dish_name = sc.next(); //菜品名字输入 if (menu.searthDish(order_Dish_name) == null) if(order_Dish_name.equals("delete")) if(order.findRecordByNum(Integer.parseInt(order_Dish_num))==null) System.out.println("delete error;"); else //onePrice[Integer.parseInt(order_Dish_num)-1] = 0; //totalPrice = totalPrice - onePrice[Integer.parseInt(order_Dish_num)-1]; //totalPrice = totalPrice - order.delARecordByOrderNum(Integer.parseInt(order_Dish_num)).getPrice(); //totalPrice = totalPrice - order.delARecordByOrderNum(Integer.parseInt(order_Dish_num)); if(order.delARecordByOrderNum(Integer.parseInt(order_Dish_num))!=null) deletePrice[i] = order.delARecordByOrderNum(Integer.parseInt(order_Dish_num)).getPrice(); totalPrice = totalPrice - deletePrice[i]; else order_Dish_portion = sc.nextInt(); //份额输入 order_Dish_Num = sc.nextInt(); //份数输入 System.out.println(order_Dish_name + " " + "does not exist"); else order_Dish_portion = sc.nextInt(); //份额输入 order_Dish_Num = sc.nextInt(); //份数输入 //添加一个点菜到records order.records[i] = order.addARecord(order_Dish_num, order_Dish_name, order_Dish_portion, order_Dish_Num); order.records[i].d = menu.searthDish(order_Dish_name); //计算单个菜品价格并加入总价 onePrice[i] = order.records[i].getPrice(); System.out.println(order.records[i].ordernum+" "+order.records[i].d.name+" "+onePrice[i]); totalPrice += onePrice[i]; //System.out.println(totalPrice); i++; System.out.println(totalPrice); class Dish String name;//菜品名称 int unit_price; //单价 //int getPrice(int portion)//计算菜品价格的方法 class Menu Dish[] dishs =new Dish[20];//菜品数组,保存所有菜品信息 //Dish dishs[] = new Dish(); public Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。 int i; for(i=0;i<2;i++) if(dishName.equals(dishs[i].name)) return dishs[i]; return null; public Dish addDish(String dishName,int unit_price)//添加一道菜品信息 int i; for(i=0;i<dishs.length;i++) if(dishName.equals(dishs[i].name)) continue; dishs[i+1].name=dishName; dishs[i+1].unit_price=unit_price; return dishs[i+1]; class Record Dish d = new Dish();//菜品 String ordernum;//序号 int num; //份数 int portion;//份额(1/2/3代表小/中/大份) public int getPrice()//计价,计算本条记录的价格 int onePrice=0; if(d.name.equals("麻婆豆腐")) if(portion==1) onePrice=d.unit_price*num; // System.out.println(ordernum+" "+d.name+" "+onePrice); if(portion==2) onePrice=(int)Math.round(d.unit_price * 1.5*num); //System.out.println(ordernum+" "+d.name+" "+onePrice); if(portion==3) onePrice=d.unit_price*2*num; //System.out.println(ordernum+" "+d.name+" "+onePrice); if(d.name.equals("油淋生菜")) if(portion==1) onePrice=d.unit_price*num ; // System.out.println(ordernum+" "+d.name+" "+onePrice); if(portion==2) onePrice=(int)Math.round(d.unit_price * 1.5*num ); // System.out.println(ordernum+" "+d.name+" "+onePrice); if(portion==3) onePrice=d.unit_price*2*num ; //System.out.println(ordernum+" "+d.name+" "+onePrice); return onePrice; class Order Record[] records = new Record[20];//保存订单上每一道的记录 /*public int getTotalPrice()//计算订单的总价 */ public Record addARecord(String ordernum,String dishName,int portion,int orderNum)//添加一条菜品信息到订单中。 Record record1 = new Record(); record1.ordernum=ordernum; //序号 record1.d.name=dishName; //名称 record1.portion =portion; //份额 record1.num=orderNum; //份数 return record1; /* 麻婆豆腐 12 油淋生菜 9 1 麻婆豆腐 2 2 2 油淋生菜 1 3 1 delete end */ public Record delARecordByOrderNum(int orderNum)//根据序号删除一条记录 int j; for(j=0;j<records.length;j++) if(Integer.parseInt(records[j].ordernum)==orderNum) return records[j]; return null; public Record findRecordByNum(int orderNum)//根据序号查找一条记录 int i; for(i=0;i<records.length;i++) if(Integer.parseInt(records[i].ordernum)==orderNum) return records[i]; return null;
SourceMonitor上代码质量分析结果:
分析:看图片可以看出在Record类中getPrice方法的复杂度较高,部分功能实现还是比较复杂
最后的提交结果:
三.踩坑心得:
~~第一次大作业7-7
踩坑:在判断是否为直角三角形时,没有加上误差判断,导致无法判断是直角三角形,后面加上误差,则输出正确;
最终代码实现:
import java.util.Scanner; public class Main public static void main(String[] args) /*输入:a,b,c代表三角形三条边 *处理:根据三角形三边特点判断三角形类型.特殊三角形判断:在判断直角三角形时,需要给一个误差判断,具体误差多少看怎么输入数据,结果保留小数如何 *输出:输出对应三角形面积 */ Scanner input = new Scanner(System.in); double a=input.nextDouble(); double b=input.nextDouble(); double c=input.nextDouble(); if(a<1||a>200||b<1||b>200||c<1||c>200) System.out.print("Wrong Format"); else if(a+b<=c||a+c<=b||b+c<=a) System.out.print("Not a triangle"); else if(a==b&&b==c) System.out.print("Equilateral triangle"); else if((a==b&&(a*a+b*b-c*c<0.001))||(b==c&&(b*b+c*c-a*a<0.001))||(a==c&&(a*a+c*c-b*b<0.00001))) System.out.print("Isosceles right-angled triangle"); else if(a==b||a==c||b==c) System.out.print("Isosceles triangle"); else if((a*a+b*b-c*c<0.000001)||(b*b+c*c-a*a<0.0001)||(a*a+c*c-b*b<0.0000000001)) System.out.print("Right-angled triangle"); else System.out.print("General triangle");
提交结果:
第一次大作业7-1
踩坑:最后提交结果限定了输出必须为float类型,而定义的变量是double类型,需要强制转换
最终代码实现:
import java.util.Scanner; public class Main public static void main(String[] args) Scanner a = new Scanner(System.in); double weight = a.nextDouble(); double height = a.nextDouble(); double BMI; BMI = weight/(height*height); if(weight<=0||weight>727||height>2.72||height<=0) System.out.println("input out of range"); else if(BMI<18.5) System.out.println("thin"); else if(BMI<24) System.out.println("fit"); else if(BMI<28) System.out.println("overweight"); else System.out.println("fat");
第三次大作业7-6
踩坑:在本题给出的输入纬度信息中秒只说明了是有小数,而没有说一定是两位小数,输出如果采用%.f输出过不了全部测试点的,应改用%s输出
改进代码实现:
import java.util.Arrays; import java.util.Scanner; public class Main public static void main(String[] args) /*输入:分别接收 度:du, 分:fen, 秒:miao *处理:公式计算 ,注意浮点型相除 *输出:按格式输出 y:小数表示结果 */ Scanner sc = new Scanner(System.in); int du= sc.nextInt(); int fen = sc.nextInt(); double miao = sc.nextDouble(); double y; y = (du + fen/60.0 + miao/3600.0); System.out.printf("%d°%d′%s″ = %.6f\\n",du,fen,miao,y);
第三次大作业7-4
踩坑:在分割一句话上,不知道如何将这句话分割出每个单词,后来查找相关知识,改进如下;
分析:由于转义字符的缘故,在转义字符前要加双斜杠 \\ \\
四.主要困难以及改进意见:
1.困难:对于菜单计价程序,我一直所困惑的点就是空指针问题,说具体点就是无法理解类之间的数据互通,比如总是会出现菜谱中存入的菜品而无法在订单类中,订单类的加入一个菜的方法无法实现,以至于一直卡住,总体感觉思路都是有的,却因为各种空指针卡住,可能总结说就是类之间的相互关系不理解吧,超级想想明白这回事;
2.改进意见:学习更多的数据结构和算法:Java开发中广泛使用的数据结构和算法非常之多,如链表、数组、哈希表、二叉树、动态规划、贪心算法等等。了解这些数据结构和算法将使您的Java编程更加高效;另外,提高写代码效率,在同样的时间内,可以完成更多的代码量,而不是用写代码的时间来堆积出,提高代码效率最好是多向厉害的人学习,但形成自己的代码风格。
五.总结:
三次大作业可以说,是对个人的升华,让我意识到面向对象的神奇之处,也让我学到了很多其他的知识点,比如对简单的语法概念的掌握,再比如最明显的,我找到了适合我的编译器,强化了在编译器的使用上的熟练,会用IDE查错调试,打包程序,学到东西同时也侧面反映出了我自身的问题所在,还有很多要学的等着我,我个人觉得还要多在java时间类的使用上多花时间,多加学习,更重要的是面向对象概念的加深深化,总之,通过三次大作业的练习,我得到更加全面的训练,思维的训练,代码能力的提升,很感谢大作业。
PTA实验1~3分析及总结
1.前言
这是第一次作业总结,经过一段时间对Java的学习,我们已经完成了三次pta作业。题目也是由易到难,由浅入深。第一次OOP作业主要考察的是我们的基本语法和对Java基本的理解。第二次作业难度上升,主要考察我们对题目的理解和基础知识的掌握。第三次作业难度大幅提升,考察我们对类的掌握与理解,更加训练我们在更为复杂的情况下多个语法的嵌套与综合运用,所以三次作业之间的关系可以说是基础与提升,是循序渐进的关系。第三次作业的第四题才开始真正考考验我们的编程能力。
2.设计与分析
第一次oop训练:
7-8 从一个字符串中移除包含在另一个字符串中的字符
设计
将两行输入存入字符数组,将第一行的字符数组一个个与第二行的比较,如果都不相同,则追加到新的字符序列上。
分析
那么就要用到StringBuffer类中的append()方法,在用toSring()转换成字符串输出。
该题目具体代码如下
import java.util.Scanner; public class Main public static void main(String[] args) Scanner input=new Scanner(System.in); String zf1=input.nextLine(); String zf2=input.nextLine(); String[] array=zf1.split(""); StringBuffer a=new StringBuffer(); for (int i=0;i<array.length;i++) if (!zf2.contains(array[i])) a.append(array[i]); System.out.println(a.toString());
以下是生成的报表
第二次oop训练:
7-3房产税费计算
这题需要用到if语句来判断契税的具体情况
其中我们有四个数据需要处理
double n=input.nextDouble();//第几次购房 double hm=input.nextDouble();//房款 double assess=input.nextDouble();//评估价 double s=input.nextDouble();//房屋面积
通过if语句的使用加上题目大意的理解很容易能够解决
以下便是具体代码的实现
import java.util.Scanner; public class Main public static void main(String[] args) Scanner input = new Scanner(System.in); float a=0; float b; float c; float d; int number=input.nextInt(); int money=input.nextInt(); int meature=input.nextInt(); float size=input.nextFloat(); if(size>144||number>1) a=meature*300; else if(size<=144&&size>90) a=meature*150; else if((size<=90)&&number<=1) a=meature*100; b=money*5; c=size*3; d=size*136/100; System.out.println(a+" "+b+" "+c+" "+d);
7-8判断三角形的类型
这一题比较考验我们新手的理解和分析能力,不过要注意判断三角形是否是直角三角形时要注意
将输入的三条边先进行合法判断,再进行各种三角型的逻辑判断
分析三角形类型判断就要运用好勾股定理,并且有的三角形有着包含关系,就像等腰直角三角型包含在等腰三角型中,要合理的减少代码量,做到简洁,可读。
if((a*a+b*b-c*c<0.00001)||(a*a+c*c-b*b<0.00001)||(b*b+c*c-a*a<0.00001)我们要通过判断两边平方约等于第三边平方,而不是直接判断他们两个相等因为两个doudle经行计算会有很多误差
代码如下
import java.util.Scanner; public class Main public static void main(String[] args) Scanner input=new Scanner(System.in); double a=input.nextDouble(); double b=input.nextDouble(); double c=input.nextDouble(); if(a>=1&&a<=200&&b>=1&&b<=200&&c>=1&&c<=200) if(a+b>c&&a+c>b&&b+c>a) if(a==b&&b==c&&b==c) System.out.println("Equilateral triangle"); else if((a==b)||(b==c)||(a==c)) if((a*a+b*b-c*c<0.00001)||(a*a+c*c-b*b<0.00001)||(b*b+c*c-a*a<0.00001)) System.out.println("Isosceles right-angled triangle"); else System.out.println("Isosceles triangle"); else if((a*a+b*b-c*c<=0.00001)||(a*a+c*c-b*b<=0.00001)||(b*b+c*c-a*a<=0.00001)) System.out.println("Right-angled triangle"); else System.out.println("General triangle"); else System.out.println("Not a triangle"); else System.out.println("Wrong Format");
生成的报表如下
第三次oop训练:题目到这一次就开始难起来了
7-3定义日期类
首先我们要学会看图,并且知道如何创建一个类
class Date
private int year,month,day;
int [] mon_maxnum=0,31,28,31,30,31,30,31,31,30,31,30,31;
public void Date(int year,int month,int day)
this.year=year;//定义年
this.day=day;//定义月
this.month=month;//定义日
这一题首先我们要输入年月日,主要的就是判断是否是闰年并且运用数组来表示月份会更加简单
具体实现的代码如下
import java.util.*; class Date private int year = 0; private int month = 0; private int day = 0; int[] mon_maxnum=new int[] 0,31,29,31,30,31,30,31,31,30,31,30,31; public Date(int year,int month,int day) this.year=year; this.month=month; this.day =day; public int getYear() return year; public void setYear(int year) this.year = year; public int getMonth() return month; public void setMonth(int month) this.month = month; public int getDay() return day; public void setDay(int day) this.day = day; public boolean isLeapYear(int year) boolean isLeapYear; isLeapYear=((year % 4 == 0 && year % 100 !=0 )||year % 400 == 0); return isLeapYear; public boolean checkInputValidity(int year,int month,int day) boolean checkInputValidity; int[] a=new int[]0,31,29,31,30,31,30,31,31,30,31,30,31; if(!isLeapYear(year)) a[2] = 28; checkInputValidity = (year>=1900&&year<=2000&&month>0&&month<=12&&day<=a[month]&&day>=1); return checkInputValidity; public void getNextDate(int year,int month,int day) int[] a=new int[]0,31,29,31,30,31,30,31,31,30,31,30,31; int d=0,m=0; if(!isLeapYear(year)) a[2] = 28; if(checkInputValidity( year, month, day)) if(month==12) if(day==a[month]) year = year+1; m = 1; d=1; else m=month; d =day +1; else if(day==a[month]) m = month + 1; d = 1; else m=month; d = day+1; System.out.println("Next day is:"+year+"-"+m+"-"+d); else System.out.println("Date Format is Wrong"); public class Main public static void main(String[] args) Scanner input = new Scanner(System.in); int year= input.nextInt(); int month= input.nextInt(); int day= input.nextInt(); Date date = new Date(year, month, day); date.getNextDate(year, month, day);
这题主要考察我们根据类图来编写类,以为第一次接触类,所以题目不难,但是要注意的是代码的可读性和可持续性,为我们写下一题打基础的
7-4日期类设计
接下来便是我们这三次作业的重头戏
下面是本题目的类图
这题其实是对上一题的代码进行扩写,同样的类进行扩写,解决不同的问题,这题有三种情况:
第一种:输出输入日期的下n天
第二种:输出输入日期的前n天
第三种:输出两个日期之间相差的天数
这三种题目的解题思路都差不多,唯一需要注意的就是闰年的二月是29天,具体思路就是将n天与365天比较,再与各个月的天数比较,这样可以减小时间复杂度。
主要是要理清楚之间的关系
以下便是具体代码
import java.util.Scanner; public class Main public static void main(String[] args) Scanner input = new Scanner(System.in); int year = 0;//定义年 int month = 0;//定义月 int day = 0;//定义日 int choice = input.nextInt();//输入选择:1.求下n天 2.求前n天 3.求两个日期相差的天数 if (choice == 1) // test getNextNDays method int m = 0;//定义要求接下来几天 year = Integer.parseInt(input.next());//得到年 month = Integer.parseInt(input.next());//得到月 day = Integer.parseInt(input.next());//得到日 DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) //如果判断为非法日期的话 System.out.println("Wrong Format");//输出 System.exit(0); m = input.nextInt();//输入要求接下来几天 if (m < 0) //m的范围 System.out.println("Wrong Format"); System.exit(0); System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");//输出 System.out.println(date.getNextNDays(m).showDate()); else if (choice == 2) // test getPreviousNDays method int n = 0;//输入要求之前几天,接下来代码和上面基本相同,不再赘述。 year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) System.out.println("Wrong Format"); System.exit(0); n = input.nextInt(); if (n < 0) System.out.println("Wrong Format"); System.exit(0); System.out.print( date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); System.out.println(date.getPreviousNDays(n).showDate()); else if (choice == 3) //test getDaysofDates method year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); int anotherYear = Integer.parseInt(input.next());//输入要求的第二年的各项数据 int anotherMonth = Integer.parseInt(input.next()); int anotherDay = Integer.parseInt(input.next()); DateUtil fromDate = new DateUtil(year, month, day);//开始年份 DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);//结束年份 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) //判断两个年份的输入是否合法 System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:" + fromDate.getDaysofDates(toDate)); else System.out.println("Wrong Format"); System.exit(0); else System.out.println("Wrong Format"); System.exit(0);
有的部分运行会超时,还有很多地方可以改进
这一题用到了上一题所写的代码,当时不能直接使用,所以代码写的没有很严谨,换了个环境可能就不能用了,所以可以在其中常用的方法中将其改的更严谨,更易修改,遵循单一原则,每个方法只做一件事,显然这题写的代码并没有全部遵循,但可以改进,让代码呈现高内聚,低耦合。
3.踩坑心得
有很多地方我们要在意细节
4.改进建议
5.总结
以上是关于关于三次pta大作业的总结报告的主要内容,如果未能解决你的问题,请参考以下文章