标签:node 随机 fat person 三次 利用 总结 init 调整
岁月不拘,时节如流。不知不觉中OO课程已经来到最后一次总结了,从刚接触多项式求导的无从下手到第四单元UML的解析,经过OO课程的苦练,自己的能力得到了很好的锻炼。闲话不多说,开始进行总结。
本单元最终的总体结构如下
本单元解析UML,笔者认为大体上可分为两步,一是建立结构,二是按需查找。其他比较重要的就是需要考虑清楚UML的结构,避免出现层次上的问题。
这一部分是十分重要的部分。对于每一个元素而言,由于本身只有最基础的id
和name
等基本属性,为了建立一个更加便于查找的结构,对每个元素创建一个自定义的元素,将基础元素封装在内,提供必要的访问接口。在细节的存储方面,由于每个元素都有独特的id
,所以采用Hashmap
存储不失为一种好的选择。
接下来是构建部分,整体上的构造传入了一个元素的大数组,缺少层次,直接使用并不合适,所以在构造函数中MyUmlGeneralInteraction
将会调用一个init()
函数,实现元素的结构建立。
三次作业中,因为需求的不同,所以在结构的建立上有一些增加和调整,但大体的思路一致。首先在元素的层面上,可以暂时把他们抽象为树形结构,例如UML_CLASS
下面挂着UML_ATTRIBUTE
,UML_OPERATION
等,UML_OPERATION
下面又挂着UML_PARAMETER
。
TODO图
这样一来就可以将元素排成一个相对有序的结构。有了这样的思想,在具体实现上相对容易,不过在这里笔者为了防止样例中有顺序错乱的情况,增加了其他的一些判断(但实际上似乎没有这样的样例)?。
到这里整体上的结构就有了,一些细节方面还需处理,例如一些平行的结点之间任然存在联系,所以再进一步,可以建立一个图模型。
例如实现了查询指令中要带上父类、接口的问题,这样的查询笔者采用dfs
。为了实现这个功能,就需要一个图的结构,当然,具体实现中为了简化实际上只记录了出边。这样整体的结构就有了。
TODO图
这是以类图为例,对于状态图而言,使用图的方式就变得更加合情合理。
有了合适的结构,查找就变得简洁。一些查询方法根据索引即可找到,细节方面需要注意异常的情况,避免出现漏判而导致类似于空指针等的异常。由于整体上限速范围较为款宽松,所以一些较为间接的查询就采用dfs
或bfs
方法。
最后一次作业需要进行合法性检查,这一次作业设计到的细节部分很多,所以也是一边等待指导书更新一边完善自己的代码。但真正改动的地方不多,因为结构部分的建立已经比较完善,几乎不需要大改动,在查找时需要注意出现了不合法现象的处理方式,抛出异常即可。
建立表达式树,化整为零。把合并和整体上的管理抽象出来,新增了一个Poly
类,其中利用map
来管理的数据。利用map
,将指数存为key
,底数作为value
,通过检测是否有key
值实现化简。
TreeNode
,所有因子、运算符继承TreeNode
类名 | 功能 |
---|---|
CstNode | 带符号整数 |
PowNode | 幂函数 |
TriNode | 三角函数 |
AddNode | 加运算符 |
SubNode | 减运算符 |
MultNode | 乘运算符 |
NestedNode | 嵌套运算符 |
复合函数由NestedNode
管理数据,举例来说函数f(g(x))
,左孩子是外层模式函数f(g)
,右孩子是内层因子g(x)
,求导时只需要按照规则实现对应外层求导乘内层函数。
总体采用生产者-消费者模式。电梯部分只进行简易移动,对于三种模式配置三种策略类适应调度。对于不同种类的电梯区分,主要在于调度器的判断,电梯只是一个电梯,并不关心其他东西。如果需要实现功能扩展,一般不需要改动电梯,需要改变电梯的相关配置类、调度器。
Strategy
类调度器设计。首先是如何分配请求的问题,主要考虑两个方面,一是电梯所在楼层,二是电梯内部人数。这两者有一定的权重,举个例子,如果电梯离某个请求很近,并且电梯内人数很少,调度器会把该请求分给这部电梯。但是如果电梯内人数很多,经过加权可能不如另一个距离较远的空闲电梯,则调度器会分给空闲电梯。新增电梯也可在此基础上进行调度,抽取工作权重较大电梯的请求,放入工作权重较小的请求,让每部电梯负载均匀。
调度器需要对请求池、电梯队列进行交互和相关状态的查询,最终进行分配。至此,调度器的工作结束,问题就变成了单个电梯的运行。
构建社交网络。关于如何合理存储相关的信息,由于输入信息中有个一个很重要的唯一的ID
,注意到这一点,HashMap
具有独特的优势。整体结构如下
MyNetwork
,实现Network
接口,最外层的结构,实现对外访问的方法。存储信息
Person[]
信息
father[]
连通分量信息
group[]
群聊信息
message[]
消息
emoji[]
表情
MyPerson
,实现Person
接口,进行人员信息的简单管理,内部有一些简单关于属性的访问和修改方法。
MyGroup
,实现Group
接口,群聊信息的简单管理可以增删改查,年龄的平均值、方差,每次访问时计算。valueSum
由于每次计算的复杂度较高,所以作为属性,在每次更新MyGroup
时维护该变量。人员的信息采用冗余存储,用HashMap
和ArrayList
同时存储。
图模型主要由上述三个类就可以构建出来,为了最短路径的效率,新增的配合堆优化的Node
类。
如第一部分所述。
封装、继承、多态,抽象,层次化,可以说如果没有OO的方法,在OO课上将寸步难行。对于每一次工程的迭代开发,一个良好的设计十分重要,到最后一个单元时,在写代码之前已经有了斟酌设计架构的习惯,这对于整体迭代是十分有帮助的。
checkStyle
中会推荐private
,因为有的东西值得暴露,有的应该自己藏好。其实在这个设计的过程中就会牵扯到类的规划等更多复杂的问题,这个方法应该由本类实现还是调用其他类的相关方法等等很多考虑。通过封装就可以有序地划分类的职责。
另外,封装带来的一大好处就是迭代时改动范围的可控性。当被调用的某一个方法内部出现了问题需要修改,外部并不用关心内部如何变化,只要接口维持不变,就只需要更改内部方法,而不用把整座大厦推倒重建。
OO课程一直强调层次化的架构设计。算法中有一个很重要的思想就是分而治之,有了层次化的思想,可以逐步解决复杂问题。
除此之外,出现需求变更或者出现bug之后也不会牵一发而动全身,可以在层次的范围内控制下来。多项式求导、电梯的层次化都十分重要。调度器层次的加入使得电梯代码不需要大改,多种同类项有序存储也给化简带来便利。
OO课程的测试十分重要,如果缺少比较完善的测试,很可能在强测环节出现大问题。可以分为以下三个大的阶段。
由于刚刚接触OO和评测机的搭建,实际上并不能产生有强度的数据,基本依赖手动构造以及随机的生成,最后利用python
进行简单验证。找bug比较依赖阅读代码的静态debug。
电梯问题,这个单元如果想要手动测试将十分困难。在了解了一部分简单的测试方法后,也能随机生成一些样例,主要用于检测死锁相关的问题,关于一些极端情况的判断能力较弱,但已经是一个很好的尝试。而且对于电梯的调度有很好的参考价值,可以根据测试来反映性能。
Junit
的单元测试,可以构造样例并检查。方便测试可以实现一个repOK
,在测试时调用该方法来检查当前状态。保证模块化的正确之后就可以很好地确保整体的正确性。之后是自动评测机,样例生成部分有了类似于面向对象的方法。将每一种查询指令构建成一个类,调用random
的相关方法来生成。不过这也主要是进行一些功能上的测试,对于极端的性能情况一般还需要手动构造。OO课程带来的任务量是很大的,在学习的整个过程中,也写下了上千行的代码。更重要的是一种思想方法上的学习,如果没有这么大的训练量,我们似乎也很难掌握如此复杂的OO方法,也不能真切地体会到OO思想方法究竟能够带来什么好处。经过一个学期的学习,真的能够感觉到自己能力的提升。
还要非常感谢很多小伙伴,面向对象并不是一个简单的事情,其中还有很复杂的设计思想和构造考虑,是很多同学、老师的指点才能让我更好地认识这种方法。
标签:node 随机 fat person 三次 利用 总结 init 调整
原文地址:https://www.cnblogs.com/ddl789/p/14939169.html