PTA题目集阶段总结(1)

发布时间 2023-03-26 12:57:09作者: 黔默聆

(1)概述

第一次

  第一次题目集涉及到的知识点都很基础,主要就是基础的输入输出、条件判断和循环语句,比如如何输入整型、实型、字符串(有空格、无空格)之类的数据和输出保留几位小数的数据和字符串等,此外条件判断语句(if、if-else)和循环语句(for、while、do-while)和C语言中是一样的,不需要另外学习。另外还考察了字符串处理(比较、截取)、字符串操作(chatAt、split)的相关知识点,“7-10 GPS数据处理”中特别考察了startsWith()方法(用于检测某请求字符串是否以指定的前缀开始)和equals()方法(比较两个字符串是否相同)。

  第一次题目集共12题,总体比较简单;1-4、9非常简单;5-8涉及到字符串操作,需要了解Java相关知识,否则比较麻烦;第10题题目较长较复杂,需要认真阅读并理解,需要了解Java中的startWith()等方法,比较复杂;11题题目不难,但是涉及到精度问题,需要不断微调并测试,比较费事;12题题眼在于求出最大公约数,需要一些思考,比如借助欧几里得算法减少时间复杂度等等。

第二次:

  第二次题目集涉及到的知识点也很基础,主要就是精度问题(double类型和float类型,保留的小数位等)和把字符串转换为字符数组、方法的调用。

  第二次题目集共9题,总体较简单;1-3、6题都是简单的计算问题,但需要仔细考虑数据精度,否则不能通过全部测试点;第4题是简单的字符串的直接定义,很好解决;5、7关于字符串,合理运用相关方法也不难,其中第5题需要考虑到特殊情况;第8题需要着重考虑到计算等腰直角三角形的精度问题,不过8、9题只要考虑周到,还是很容易的。

第三次:

  第三次题目集涉及到一些专业的Java知识,比如私有属性,LocalDate类型、类的设计和创建、方法的定义、构造、调用、setter、getter方法等等。

  第三次题目集共4题,题目逐渐脱离了C语言的影子,需要进一步理解和使用Java,比前两次更难也更专业一些;第1题属于经典例题,在课本上就有详细的讲解和说明,依葫芦画瓢就能做出来;第2题比第1题复杂,涉及的数据比较多;第3题在第2题和训练集02最后一题的基础上就能做出来,也挺简单;第4题是所有题目中最难的,需要考虑各种各样的情况并完成大量的计算,调试起来费时费心,难度比之前大了不少。

 

(2)设计与分析

OOP训练集02 7-8 判断三角形类型

 

 

  题目将要求表达地很明确了,甚至还贴心地由特殊到一般给排了序,并且提示了在一行中输入的三角形的三条边的值是实型数,所以我们直接上手写就好,按照一些数学公式就可以完成大部分要求,不过需要格外注意第(4)点:

 

 

 

OOP训练集03 7-3 定义日期类

  本题很贴心的提供了设计好的类结构,在图的指导下写出各个方法就行了,判断闰年的方法我们已经很熟悉了,直接写就行了;但在判断合法日期(checkinputValidity())和计算下一天(getNextDate())时需要注意一些问题:

 

OOP训练集03 7-4 日期类设计

 

 

 

  第四题也没要我们自己设计,还提供了主方法,照着题目要求写就好了,其中checkInputValidity()和isLeapYear(int year)方法可以照搬第三题,compareDates(DateUtil date)(比较当前日期与date的大小(先后) )和equalTwoDates(DateUtil date)(判断两个日期是否相等)也是很容易完成的, showDate()以“year-month-day”格式返回日期值一行代码就能搞定,难点在于getNextNDays(int n)(取得year-month-day的下n天日期)、getPreviousNDays(int n)(/取得year-month-day的前n天日期)和getDaysofDates(DateUtil date)(求当前日期与date之间相差的天数 ),时间跨度较大,计算量也很大。其中取得后n天日期和前n天日期有异曲同工之妙,知其一便可知其二,用循环就能做完。

 

 

 

 

 

 

 

(3)采坑心得

OOP训练集01 7-2 身体质量指数(BMI)测算

  一开始看到题目,不假思索地就写了“BMI = (weight / height) * (weight / height)”,结果只过了一个测试点,百思不得其解,最后发现是理解错了。

 

 

   所以做此类用文字题目时,要思考一下题面描述是否有歧义,不要看到错误就害怕,在那里拼命修改程序,将想到的可能性多试试,没准就是这里出了点小问题。

 

OOP训练集01 7-4 快递运费

 

 

  这一题遇到了两个问题,一个是题目迷惑了,在计算cost时就把(x+0.5)放进去了,计算出来的结果由明显的误差,后来发现只要在计算完之后对cost加一个0.5来完成四舍五入的操作就行了(详情可见上方右图中的注释);再者就是,计算时忘记减掉首重了,这就不只是误差的问题了,答案直接差了十万八千里。不过都是小问题,改一下就好。

 

OOP训练集01 7-11 求定积分

  真的是被这一题坑惨了······不多说了,直接上图:

 

 

  一开始就不知道为什么错了,然后投机取巧用了高数中教的公式,得了4分,之后就是不断的试啊试,从3月2日试到3月4日,中途还神志不清地弄出了两次编译错误,具体细节已经记不清了,好在当时留了些注释,当时的心得都在里面了:

  哦,对了,一开始我是以整型输入的定积分的上限和下限,错到怀疑人生;更坑的是,最后交上去的测试点全部通过的程序运行出来的结果和输出样例是不符的,能输出和输出样例相符合的结果的程序又通过不了其他的测试点。

 

 

 

OOP训练集02 7-1 长度质量计量单位换算

  这题也没什么好说的,纯纯是数据精度问题,直接上图:

 

 

 

OOP训练集02 7-3 房产税费计算2022

  这一题是单位的问题,注意房款和评估价的单位都是万元,而印花税也相当的应该是万元;但是交易费和测绘费的单位是元,而且最后都要以元为单位输出;这里就出了一点问题,需要把万元转换为元。

 

 

 

OOP训练集02 7-6 巴比伦法求平方根近似值

  一开始没看懂题目的意思,以为输出的是nextGuess,理所当然地错了。

 

 

 

  还要注意一个问题是,lastGuess是有赋值的,但nextGuess没有,所以在进入循环前要先初始化nextGuess,否则会出错。

 

(4)改进建议

OOP训练集02 7-5 学号识别

 

 

   这题为了判断学号的长度和拆分学号,我是以字符串形式输入的学号,然后再将字符串转换为字符数组,之后在检验学院编号不是01、02、03、20其中之一时,由于有2个字符,采取了一种很傻的方式——一个个对照,输出时也是一个字符一个字符地输出的;后来参考了别人的代码,发现可以直接用substring()来切割,然后用equalsIgnoreCase()来比较,而且可以把切割出来的字符串赋值给其他字符型变量,判断和输出都变得简单了,而且这样写也更加规范。

 

 

 

OOP训练集01 7-8 从一个字符串中移除包含在另一个字符串中的字符

  这道题前前后后已经被我提了几次了,这里就不多说了,直接上图:

 

OOP训练集02 7-7 二进制数值提取

  这道题的情况和上一题差不多,不过这两种方法写起来其实差不多,都不会太费事,但是方法一有两个循环,一个遍历字符串数组检测输入是否合法,另一个再把数组遍历一边检测和输出结果,还写了很多判断语句,又是flag又是用break;明显方法2更简洁直观。

 

 

(5)总结

  开始第一个题目集的时候,脑子里完全是一片空白的,各种输入、输出、定义、循环语句都要一个个搜索,Java的基本语法愣是记了好久。虽然老师一再强调这个题目集极其简单,对于一没有基础、二没有经验的我来说,完成地还是相当吃力。不过好在跌跌撞撞做完之后,新解锁了许多Java中的方法,最主要的就是String类,真的提供了许多简洁方便的方法,大大减轻了编程的压力,也打开了新世界的大门。与C语言不一样,C语言基本只需要读懂题目,直接硬写就好,Java比较讲究设计,动手之前需要先想想有没有什么好方法可用、该怎么用之类的。比如“7-8 从一个字符串中移除包含在另一个字符串中的字符”,一开始想都没想,用的就是类似C语言中的方法,将字符串转换为字符数组,各种循环遍历,判断、输出,结果一转头,发现了String类中的replaceAll()方法,刨去其基本框架和输入输语句,一句话搞定;除了注意一下字符串可能存在空格,需要以nextLine()输入以外,根本不需要自己再操心。有了第一个题目集的基础,处理起第二个题目集就比较得心应手了,比如“7-7 二进制数值提取”中一开始用到的toCharArray()——把字符串转换为字符数组,就是在“7-8 从一个字符串中移除包含在另一个字符串中的字符”中学到的。这样看来,即使Java提供了很多方法,拿到一道题后,我们还是应该先尝试着用自己的方法写一写,对于我们这种初学者,一味依赖语言的便利不利于提升我们的编程能力,也不利于我们打下扎实的基础。另外还学习了一下Java中数组的用法,在“7-1、7-3、7-6”的锤炼下,对于数据精度也有了更深的认识和感受。哦,另外在“7-9 求下一天”中初步提到了方法,不过是包含在Main类中的,原理和C语言中的函数差不多,不过是写法不太一样,在C语言的知识加持下,很容易就搞定了;第三个题目集将我们带入了类的新世界,同样是从头学起,完成这4道题后也收获了许多,私有属性、有参构造、无参构造、setter类、getter类现在是信手拈来。学习到了类和方法后,主函数是越来越精简好看了。

  但是即便了解了这么多方法,却没有特别深入的了解,编程的时候具体也想不出这里方便用哪种方法,还要点开收藏夹,一条条翻,大有“瞎猫碰上死耗子”的意味,找到之后也不一定会用,还得现找示例,现学现用,用完之后就把页面关了,开始做下一道题,做完了再一回头,完蛋,忘记上一题该怎么写了。即便当时点开再复习了几遍,第二天一早起来也绝对忘光光。此时我还勉强能记得点chatAt()、split()、startwith()、set()、StringBuilder()什么的,但要问我怎么用,不知道,忘了;问为什么不多记一下,记了,但是记不住。也就是说,还是做的题少了,需要多练练。就像高中的一个同学这学期在上C语言课,遇到各种各样的问题,给她解答了一通后,她问我是怎么这么了解这些东西,我答:多做题,报错报多了就记住了。其实也不是简单的报错问题,就是说明了实际操作比纯理论学习更利于锤炼我们的能力。不过现在也确实是非常繁忙,基本上没什么时间刷题,再加之基础知识储备不足,完成一道题极为艰难,比如题目集3的最后一题,从21:30开始,感觉也没干什么,“唰”地一下就凌晨1:30了,还有4个测试点没过,只能第二天早上起来继续调试。所以说,虽然实操很重要,但是没有理论知识的支撑,刷再多题都是虚的,等于只记住了个壳子,却不能深入理解其中的奥妙。

  以我目前的水准,对老师和实验也没什么意见,等我先把自己的水平提高后再评价其他吧。

  其实恰恰是作为初学者的我们,在每一次编程中都能收获很多,获得难言的满足感,不要畏惧题目难,磨练本领还看它。这次的阶段性总结就到这里,继续努力,砥砺前行!