oo——第三单元总结
前言
第三单元是我们学习oo以来第一次接触JML。这一单元的三次作业和以前一样,采用了难度递进的方式,而且前一次作业的设计思路在下一次作业都多多少少有些体现(或者说是在其基础上做出的改进)。而且本单元作业在理解了JML的基础上来做,实现起来并不困难,难点在于如何提高自己代码的性能。本文分为四个部分:首先是JML语法基础;我的设计架构以及性能优化;debug以及测试样例的自动生成;心得体会。
JML语法基础
首先简要介绍一下JML语法基础。
JML以javadoc注释的方式来表示规格,每行都以@起头。有两种注释方式,行注释和块注释。其中行注释的表示方式 为 //@annotation ,块注释的方式为 /* @ annotation @*/。JML的表达式是对Java表达式的扩展,新增了一些操作符和表达式。其中,新增的一些表达式分为原子表达式和量化表达式。原子表达式有:\result表达式,表示一个非 void 类型的方法执行所获得的结果,即方法执行后的返回值;\old( expr )表达式,用来表示一个表达式 expr 在相应方法执行前的取值,以及\not_assigned(x,y,...)表达式等。量化表达式有\forall表达式、\exists表达式、\sum表达式、\product表达式、\max表达式、\min表达式等。新增的操作符有:子类型关系操作符,等价关系操作符和变量引用操作符。除此之外,方法规格是JML的重要内容。方法规格的核心内容包括 三个方面,前置条件、后置条件和副作用约定。其中前置条件是对方法输入参数的限制,如果不满足前置条件,方法 执行结果不可预测,或者说不保证方法执行结果的正确性;后置条件是对方法执行结果的限制,如果执行结果满足后 置条件,则表示方法执行正确,否则执行错误。副作用指方法在执行过程中对输入对象或 this 对象进行了修改(对 其成员变量进行了赋值,或者调用其修改方法)。
设计架构以及性能优化
第一次作业内容比较简单,主要目的是为了让我们熟悉JML语法,在此不做过多分析。这里分析一下第二第三次作业。
第二次作业在第一次作业的基础上,引入了一些图论的知识。在实现时,由于指导书给出了明确的指示——PATH_ADD和PATH_REMOVE不超过20条。出于这一点考虑,我把第二次作业涉及的最短路径的运算分散到了每一个PATH_ADD和REMOVE,就是每一次增删路径,都会对任意两点之间的最短路径进行重新运算并保存(听起来似乎很浪费,但是有20条指令限制的保护,起码可以保证不超时)。这样,在要用最短路径的时候,直接取用就好了。第三次作业就是在第二次作业的基础上加入了换乘的概念。但就是加入这一简单的概念,让整个问题复杂了许多。在解决这一问题时,我没有找到太好的解决办法,采用了拆点的方式来解决换乘。基本思路就是,不同path上的相同点在计算最低票价和最低不满意度时视为不同的点。(最低票价和最低不满意度都用迪杰特斯拉算法,当作最短路径来算,权值不同而已)
总体架构上,我除了题目要讲求的两个类之外,还单独加入了一个类,用来封装关于图的操作,比如每次加入新的path,都要存储和更新之前存储的任意两点之间的最短路径,最低票价,最低不满意度,最少换乘次数等。这些量各自都用一个图来存储,我把这些图,以及对这些图的操作都放在这个类里(全部都用静态变量和静态方法),每次要用到,或者要更新时,就访问这个类。
心得体会
这一单元让我感触最大的,是hash表的神奇之处——他能够将一段时间复杂度为o(n)甚至更多的遍历,改变成时间复杂度为o(1)的遍历。因为在这次作业之前,我没怎么遇到过程序运行时间上限的要求,所以在这之前,我一般都是选用ARRILIST来解决这一类的问题,但是ARRILIST只要是需要遍历一次,就有o(n)的时间复杂度,一旦出现嵌套遍历的情况,就会出现o(n)以上的时间复杂度。然而,hashmap就不存在这种问题了,因为它是通过hash值作为key值,用所在类的hashcode方法来计算相应的value值存储位置,时间复杂度为o(1)。而且,hashmap还有一个好处就是,他存储的不止是一个值,而是一对键值对,这样一对相互关联的值实际上都存储在了hashmap,比如path和pathid,就可以用pathid作为键值来存储path(整型类的hashcode是已经写好的不用重写,比较方便),这样一来,path和pathid都被存储了。
bug分析以及测试数据的自动生成
dubug
本单元作业还有一个难点,那就是debug,尤其是强测互测之后,那些强侧和互测的数据你根本看不出来什么(太多了),所以我以往面向评测机debug的方法已经不再实用,因为每个bug都相当于一个前两单元中测没有返回信息的点!
JMLUnit
package
demo;
public
class
Demo {
/*@ public normal_behaviour
@ ensures \result >= num1;
@ ensures \result >= num2;
@ ensures \result >= num3;
*/
public
static
int
compare(
int
num1,
int
num2,
int
num3) {
int
max;
if
(num1 > num2) {
max = num1;
}
else
{
max = num2;
}
if
(max < num3) {
max = num3;
}
return
max;
}
public
static
void
main(String[] args) {
compare(
114
,
1919
,
1111
);
}
}
执行javac -cp jmlunitng-1_4.jar
运行测试文件得到的结果是:
[TestNG] Running:
Command line suite
Failed: racEnabled()
Passed: constructor Demo()
Passed:
static
compare(-
2147483648
, -
2147483648
, -
2147483648
)
Passed:
static
compare(
0
, -
2147483648
, -
2147483648
)
Passed:
static
compare(
2147483647
, -
2147483648
, -
2147483648
)
Passed:
static
compare(-
2147483648
,
0
, -
2147483648
)
Passed:
static
compare(
0
,
0
, -
2147483648
)
Passed:
static
compare(
2147483647
,
0
, -
2147483648
)
Passed:
static
compare(-
2147483648
,
2147483647
, -
2147483648
)
Passed:
static
compare(
0
,
2147483647
, -
2147483648
)
Passed:
static
compare(
2147483647
,
2147483647
, -
2147483648
)
Passed:
static
compare(-
2147483648
, -
2147483648
,
0
)
Passed:
static
compare(
0
, -
2147483648
,
0
)
Passed:
static
compare(
2147483647
, -
2147483648
,
0
)
Passed:
static
compare(-
2147483648
,
0
,
0
)
Passed:
static
compare(
0
,
0
,
0
)
Passed:
static
compare(
2147483647
,
0
,
0
)
Passed:
static
compare(-
2147483648
,
2147483647
,
0
)
Passed:
static
compare(
0
,
2147483647
,
0
)
Passed:
static
compare(
2147483647
,
2147483647
,
0
)
Passed:
static
compare(-
2147483648
, -
2147483648
,
2147483647
)
Passed:
static
compare(
0
, -
2147483648
,
2147483647
)
Passed:
static
compare(
2147483647
, -
2147483648
,
2147483647
)
Passed:
static
compare(-
2147483648
,
0
,
2147483647
)
Passed:
static
compare(
0
,
0
,
2147483647
)
Passed:
static
compare(
2147483647
,
0
,
2147483647
)
Passed:
static
compare(-
2147483648
,
2147483647
,
2147483647
)
Passed:
static
compare(
0
,
2147483647
,
2147483647
)
Passed:
static
compare(
2147483647
,
2147483647
,
2147483647
)
Passed:
static
main(
null
)
Passed:
static
main({})
===============================================
Command line suite
Total tests run:
31
, Failures:
1
, Skips:
0
===============================================
oo——第三单元总结的更多相关文章
- OO第三单元作业总结
OO第三单元作业总结--JML 第三单元的主题是JML规格的学习,其中的三次作业也是围绕JML规格的实现所展开的(虽然感觉作业中最难的还是如何正确适用数据结构以及如何正确地对于时间复杂度进行优化). ...
- 规格化设计——OO第三单元总结
规格化设计--OO第三单元总结 一.JML语言理论基础.应用工具链 1.1 JML语言 JML(java modeling language)是一种描述代码行为的语言,包括前置条件.副作用等等.J ...
- 【OO学习】OO第三单元作业总结
[OO学习]OO第三单元作业总结 第三单元,我们学习了JML语言,用来进行形式化设计.本单元包括三次作业,通过给定的JML来实行了一个对路径的管理系统,最后完成了一个地铁系统,来管理不同的线路,求得关 ...
- OO第三单元(地铁,JML)单元总结
OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...
- OO第三单元——基于JML的社交网络总结
OO第三单元--基于JML的社交网络总结 一.JML知识梳理 1)JML的语言基础以及基本语法 JML是用于java程序进行规格化设计的一种表示语言,是一种行为接口规格语言.其为严格的程序设计提供了一 ...
- OO第三单元作业——魔教规格
OO第三单元作业--魔教规格 JML的理论基础和相关工具 JML(Java Modeling Language,Java建模语言),在Java代码种增加了一些符号,这些符号用来标志一个方法是干什么 ...
- OO第三单元个人总结
OO第三单元个人总结 JML理论与基础与应用工具链 JML是什么? Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 .它结合了Eiffel的契约设计方法 和Larch ...
- 2020 OO 第三单元总结 JML语言
title: 2020 OO 第三单元总结 date: 2020-05-21 10:10:06 tags: OO categories: 学习 第三单元终于结束了,这是我目前为止最惨的一单元,第十次作 ...
- 2020北航OO第三单元总结
2020北航OO第三单元总结 本单元要求是根据JML规格完善代码,初看是一个简单的代码照搬实现的东西,但最后才发现由于CPU时间的限制,还考察了大量优化策略及数据结构中关于图的知识,是一次非常注重细节 ...
- OO第三单元作业(JML)总结
OO第三单元作业(JML)总结 目录 OO第三单元作业(JML)总结 JML语言知识梳理 使用jml的目的 jml注释结构 jml表达式 方法规格 类型规格 SMT Solver 部署JMLUnitN ...
随机推荐
- ch2_8_2求解幸运数问题
思路:f(x)进行十进制每位相加,g(x)进行二进制每位相加,比较是否相等即可. 小明同学学习了不同的进制之后,拿起了一些数字做起了游戏.小明同学知道,在日常生活中我们最常用的是十进制数,而在计算机中 ...
- 使用 dynamic 类型让 ASP.NET Core 实现 HATEOAS 结构的 RESTful API
上一篇写的是使用静态基类方法的实现步骤: http://www.cnblogs.com/cgzl/p/8726805.html 使用dynamic (ExpandoObject)的好处就是可以动态组 ...
- SQL注入靶场实战-小白入门
目录 SQL注入 数字型 1.测试有无测试点 2.order by 语句判断字段长,查出字段为3 3.猜出字段位(必须与内部字段数一致)(用union联合查询查看回显点为2,3) 4.猜数据库名,用户 ...
- pwn题命令行解题脚本
目录 脚本说明 脚本内容 使用 使用示例 参考与引用 脚本说明 这是专门为本地调试与远程答题准备的脚本,依靠命令行参数进行控制. 本脚本支持的功能有: 本地调试 开启tmux调试 设置gdb断点,支持 ...
- ss 命令简介
1. 简介 ss 使用 netlink 与内核 tcp_diag 模块通信获取 socket 信息,用法和输出结果类似于 netstat 命令 语法格式如下 ss [options] [ FILTER ...
- [Fundamental of Power Electronics]-PART II-7. 交流等效电路建模-7.5 状态空间平均 7.6 本章小结
7.5 状态空间平均 现有文献中已经出现了很多变换器交流建模的方法,其中包括电流注入法,电路平均和状态空间平均法.尽管某种特定方法的支持者可能更愿意使用该方法去建模,但所有方法的最终结果都是等效的.并 ...
- 使用 nodejs 中的 http 模块实现几个超实用的工具
nodejs 方便了我们前端开发者进行一些服务端上的操作,可以进行无缝地衔接.像其他一些后端语言,如 php, golang, java 等,都需要一定的学习成本,而 nodejs 则就是为前端开发者 ...
- Dynamics CRM修改密码界面
我们再实施Dynamics CRM的过程中经常会被客户吐槽没有一个修改密码的页面.市面上也有一些人通过自己操作AD库进行修改密码的解决方案不过多多少少会有一些BUG存在.其实ADFS提供了一个修改密码 ...
- SpringBoot项目打包部署
部署方式 SpringBoot项目可以通过jar包或者war包部署在服务器上,因为jar包更适合前后端分离的项目,所以这里我们使用jar包的方式. 添加maven支持 <!-- 这个插件,可以将 ...
- 让你的Windows/Linux玩上Switch!
1 前言 某天在Github上面看到了两个Switch的模拟器: yuzu Ryujinx 于是就想动手想尝试一下在Linux上面玩上Switch. 本文首先简单介绍一下两个模拟器,接着是两个模拟器的 ...