10到16周学习总结
一.前言
10到16周,我们学习了如何对一个程序进行封装,以保持它的稳定性,也学习了Java的对象容器,容器类有两个类型:容器的类型,元素的类型,一般情况下,我们并不知道要创建多少对象,或者以何种方式创建对象。数组显然只能创建固定长度的对象,为了使程序变得更加灵活与高效,Java类库提供了一套完整的容器类,具备完善的方法来解决上述问题。之后我们学习了Java的程序设计原则,通过这些原则用来约束我们对于程序设计的规范性,提升我们的代码质量。然后我们学习了抽象类与接口,抽象类用来隐藏具体的细节信息,所有的子类使用的都是相同的方法原型,其中包含了调用该方法时需要了解的全部信息;强迫子类完成指定的行为,规定所有子类的“标准”行为。与接口不同,抽象类中的语句都是只定义不进行实现。而接口可以减少代码的书写(上边分析的代码重载),提高了代码的可维护性和扩展性,在团队合作中,提高代码的规范性。之后我们学习了javafx,通过javafx设计一个完整的桌面程序,也就是做一个界面。
这几周的pta大作业是电信计费系列,相比于之前的多边形系列在逻辑上要简单很多,如果不参照类图的话很快就可以写出来,这三道题在逻辑上是逐层递进的,题目要求我们设计一个电信计费程序,也是我们首次面对客户的角度设计程序,所以要考虑到很多使用方面的因素,这个题难点在,给出了一个类图,因为这个题目的情况很多,先是分了座机手机和短信,后续还会有手机的套餐计费,然后每个情况又存在打电话和接电话的位置不同,计费模式也不同,导致如果写在一个class里就会变得非常臃肿,可读性也很低,所以题目帮助我们将整个程序的逻辑分块,变成了一个很条理的程序。
二.具体分析
- 座机计费程序
题目要求我们设计一个程序来统计在南昌市内开户的所有座机用户在一个月内花费的花费,由于座机是固定的,所以拨打电话人的位置肯定永远都在南昌市内,然后将收费模式分为,在南昌市内,在南昌市外但是在江西省内,之后就是在江西省外但是在国内这三种收费模式,下面附上我这道题的代码和类图

首先用户的输入是要开户,要先输入一个字符串类型的开户数据,那么问题就是如何检测输入的合法性,就像之前的多边形问题一样,检测用户输入合法性就需要将用户输入的信息拆解开来,存放到不同的字符串数组然后挨个判断。就好比说这道题,用户输入的是u-079186300001 0,u-是用来检测用户输入的是开户数据还是通话记录,因为用户在输入的时候会先输入很多开户数据,然后再输入通话记录数据,所以就可以把u-先用split方法分开,剩下的电话号码和0就说明他是座机开户,因为这道题只考虑座机开户,所以就不用在考虑了,所以我们只需要考虑用户输入的电话是不是7-8位的数字。我一开始采用了try语句来判断是否是数字,不是的话就返回错误,如果格式正确的话就存入一个字符串数组,然后再放到userrecords这个arraylist里。之后我发现其实可以不这么做,只需要使用正则表达式就可以直接判断整条数据是不是符合格式的,然后再用split方法把电话号码分割开来,这样就可以得到有效数据了。把所有的有效数据存入user类中,一个电话号码也就是一个用户,将所有的user类对象放到一个arraylist中,这就是主函数中要做的事。下面要完成的就是如何区分南昌市内,在南昌市外但是在江西省内,之后就是在江西省外但是在国内这三种收费模式了,这里题目将每一个号码都创建了一个类,在这个类中有许多arraylist,分别是市内接打电话,省内接打电话,国内接打电话这几种通话记录,所以我们在这里要将每一个号码的每一条通话记录导入。所以就又涉及到用户输入的第二钟数据,他的格式是这样的:t-13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20,首先是t-依然不用管,然后这是手机的电话,所以显示手机号码,后面跟着的几位是区号,第二个电话号码是接电话的人的电话号码,后面依然是接电话人的区号,然后是开始打电话的时间和结束打电话的时间,这里的两个时间用的是Date数据类,对于检测是否合适仍然使用正则表达式可以,因为座机的输入格式和手机不一样,位数和后面的区号都不一样,所以对于用户输入的数据,我们需要分四类,分别是座机打座机,座机打手机,手机打座机,手机打手机四种,然后在写四个不同的正则表达式就可以完全正确的检测格式是否符合。

当我们完全检测了格式之后,就开始通过判断区号的方式来检测地区,如果区号是南昌市的但是接电话的人不是,那就不属于南昌市内的扣费规则,由于这道题只考虑座机,所以打电话的人肯定是座机,而且永远在南昌市内,所以我们只需要看接电话的人在什么位置然后根据不同的地区,把这条通话记录分到不同的arraylist中去,这里要注意一点,我之前出了错,那就是如果一条通话记录即在打电话中,有在接电话,那么这个电话号码既要存在打电话的list中也要存在接电话的list中,然后题目明确要求不考虑时间重合或者是自己给自己打电话这种特殊情况。当分好类后,剩下的部分就简单了,只需要将他们按照不同地区分给不同的chargemode里的子类chargerule就可以了,然后再在每个计费规则中写上自己计费规则的计算,最后在主函数中直接输出user类的花费余额就可以了。这就是这道题的全部解析。

2.手机以及短信计费程序
这两道题其实对于上面的逻辑完全适用的,唯一的区别就是在检测区号的时候,可能算法会有所不同甚至会更简单,因为座机的区号再座机的电话号码中,还需要使用分割方法把string分割出来再进行判断,而手机和短信的输入数据格式,直接就把区号给了我们,所以我们直接对比就可以,然后再在收费模式类中补充几个计费的计算式子就可以了。而短信则更加简单,输入数据抛开电话号码之后直接当作短信本身的内容读取就可以,再算一下长度来计算话费就可以了。
这就是我对这三道题的理解。

三.总结
对于我最后两道题的写法,我觉得过于繁琐,我有很多算法类似的步骤,我完全可以将他们写成一个个方法来省去我的步骤,我设置了很多的变量来,例如条件满足这个变量就为1,不满足就为0这种类似的做法有很多,导致代码的可读性大大降低。题目中的有些问题很有意思,比如区号是四位也可能是三位,这就像一个冷知识一样穿插在题目中,前面我没说,我认为这种东西就没什么好说的,我实在想不出有什么技术含量。PTA的意义,我认为主要是如何设计,有些极其繁琐的细节问题,我认为主要归结于出题人如何写测试点,而不是我如何设计,我设计有多好也不可能面面俱到,就像时间判断一样,我用时间类判断竟然不对,只能用正则表达式,如果这样的问题在之后的项目中乃至以后的工作中遇到,有关于繁琐细节的问题那就非常值得思考了。在学习了继承和多态之后,我的代码有了非常大的改变,就像在c语言中掌握了链表一样,可以通过很简短的代码来表达很复杂的逻辑,这也是面向对象程序设计这门课的精髓所在,我在这次做题目的过程中学习到了很多新的方法,例如保留小数的方法等等。为了缩减代码我废了很多心机,甚至翻出了高中的数学笔记本来看有没有更简单的算法,在以后的学习中,我还需要对方法的构建进行更深入的学习,因为有一个好方法,代码的可读性将会大大的提升。同时,我还需要回归课本,书中有许多代码示例,我需要仔细地将他们研读,变为自己的东西,以上就是我对本次题目的总结。

浙公网安备 33010602011771号