OO第三单元总结~~

OO第三单元总结~~

17373301 校怡哲

 

一、梳理JML语言的理论基础、应用工具链情况


  Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为。它结合了Eiffel的契约式设计方法和Larch接口规范的基于模型的规范方法,以及一些细化演算的元素。
  jml现在已经得到了十分广泛的应用,在各个大工程里面都不可或缺,因为大的工程都是多人合作,所以对于接口函数的规格描述,以及自己代码功能的描述,都需要依靠jml来实现,它也很好的规范了大家的代码习惯

  JML表达式包括原子表达式,量化表达式,集合表达式,操作符等等, 其方法规格包括pre-condition  post-condition等等,类型规格有不变式和状态变化约束式。

  JML的应用工具链情况:OpenJML(静态检查)、JMLUnitNG(自动测试)、Junit(用于对于单独方法的单元测试)、 JMLdoc(生成jml)



二、部署SMT Solver

暂时没搞出来quq



三、部署JMLUnitNG/JMLUnit,针对Graph接口的实现自动生成测试用例

测试代码:

public class Test {

    /*@ public normal_behaviour

      @ ensures \result == x*y;

    */

    public static int mult(int x, int y) {

        return x*y;

    }

 

    public static void main(String[] args) {

        compare(2,3333);

    }

}

生成测试文件:



 

四、架构设计

第一次作业中,我们仅仅完成了path类和pathcontainer类,这其中包括的方法没有什么难度 ,重点在于怎么做才不会tle,看到助教说自己写容器只会是负优化,所以我在写的时候就使用了JAVA语言里面自己的容器例如arraylist,hashmap,hashset,在这些容器中添加删除或者查找,只需要使用其自己的接口就可以了。

第二次作业,pathcontainer升级成了graph,在这之中增加了几个比较有难度的方法,即查看两个点是否相连,查看两个点的最短距离等等。这次作业中我采用的结构是:维护一个点集,边集和距离集,我采用的是floyd算法,由于这个算法其实在每次增删路径的时候都需要重新算一遍距离集里的内容,不过样例里面说到增删的指令少于20条。floyd的好处是多源最短路,且复杂度也是稳定的n3,所以每算一次就能算所有,之后在问询的时候就能够直接查询,大大的减少时间。还有一个也能节省一些时间的方法,就是:问询的时候再重新算,比如说连着几次增删,不是每次增删完重算,而是增删完的第一次问询的时候重算。

第三次作业的难度相比于之前两次作业更大一些,这次的地铁系统需要查询最短路径,最小换乘,最小票价,最小不满意度和联通块数。由于上一次的距离集是使用hashmap存储的,导致了tle,所以这次全部使用了静态数组来存储,由于点的大小可能为负数等等,所以需要建立起一个点id到静态数组下标的一个映射,在增删点的时候维护。这次的算法使用了完全图floyd的算法,我觉得这是一个十分妙又简单暴力的算法。
这次作业的结构,由于查询那几种数据实际上是使用了一样的方法,只是边的权重不同,所以我在写的时候单独写了一个weight类,专门用来计算和问询,这样写的时候能够更加清晰。



五、按照作业分析代码实现的bug和修复情况


  第一次作业的bug几乎都是来自于tle的,因为只要不是手搓容器,基本上所有的操作只是调用接口就可以了,功能也很简单,几乎不可能出错。当时我在强测中tle了三四个点,在修复bug的时候,我发现在distinctnode方法中,我每次问询的时候都要新建一个hashset重新算一遍,所以用时很长。所以我改成维护一个hashmap点集,是一个id~重复次数的map。

  第二次作业,是一次非常惨痛的教训,wa与tle齐飞。当时扫了一遍jml觉得自己大概记住了。结果在截止时间之前的几个小时,我突然想起来有一个起始点等于终点返回0或者返回TRUE这一回事,所以我就打开我的作业,在isConnected、getShortestPathLength函数的最开始直接加上了一个判断语句,就没再看了:

if (i == i1) {

                return 0;

            }
  结果强测几乎全wa,这个if应该加在异常判断之后啊摔!万一这个点根本不存在呢quq我佛了
  改完了wa改tle,这个主要是吧hashmap存储距离集改成静态数组。
  第二次作业互测开始的时候风平浪静,岁月静好,我还以为还像从前一样,直到出现了一个18/28的兄dei,我就交了一个指导书上的例子,结果hack到了一个人,当时我慌了()

  第三次作业写的比前两次要好一点wa了一个点,tle了一个点。wa是因为数组边界没处理好,导致爆异常,我觉得tle可能是因为我的联通块查询的算法,使用了染色法,并且每次都要造一个arraylist和无数个hashset。

六、心得体会
  这几次作业的难度循序渐进,不过总的来说我觉得比前两个单元的难度要小一些,主要是致力于我们对于jml的阅读和掌握,还有一些算法和对于结构的思考。
  对于这几次作业的反思,我觉得我第三次作业的结构还可以再优化,当时我交之前发现其实单条路径也需要使用floyd算法算出该路径中的最短路,因为路径中可能存在环路之类的,由于当时时间比较紧张,且我的floyd直接写定了操作某个数组,我甚至只是把floyd几乎复制了一遍,其实我应当把floyd算法重新写一下,让他的灵活度稍微大一点。



 

 

 

 

 

posted @ 2019-05-22 17:51  17373301  阅读(150)  评论(0编辑  收藏  举报