哈工大2022软件构造lab2

 

目录

1 实验目标概述·· 1

2 实验环境配置·· 1

3 实验过程·· 1

3.1 Poetic Walks 1

3.1.1 Get the code and prepare Git repository· 2

3.1.2 Problem 1: Test Graph <String>· 2

3.1.3 Problem 2: Implement Graph <String>· 3

3.1.3.1 Implement ConcreteEdgesGraph· 3

3.1.3.2 Implement ConcreteVerticesGraph· 6

3.1.4 Problem 3: Implement generic Graph<L>· 8

3.1.4.1 Make the implementations generic· 8

3.1.4.2 Implement Graph.empty()· 9

3.1.5 Problem 4: Poetic walks 9

3.1.5.1 Test GraphPoet· 9

3.1.5.2 Implement GraphPoet· 10

3.1.5.3 Graph poetry slam·· 12

3.1.6 Before you’re done· 13

3.2 Re-implement the Social Network in Lab1· 13

3.2.1 FriendshipGraph类·· 13

3.2.2 Person类·· 15

3.2.3 客户端main()· 16

3.2.4 测试用例·· 17

3.2.5 提交至Git仓库·· 18

4 实验进度记录·· 19

5 实验过程中遇到的困难与解决途径·· 19

6 实验过程中收获的经验、教训、感想·· 19

6.1 实验过程中收获的经验和教训·· 19

6.2 针对以下方面的感受·· 20

1.实验目标概述

本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象编程(OOP)技术实现 ADT。具体来说:针对给定的应用问题,从问题描述中识别所需的 ADT;

  1. 设计 ADT 规约(pre-condition、post-condition)并评估规约的质量;
  2. 根据 ADT 的规约设计测试用例;
  3. ADT 的泛型化;
  4. 根据规约设计 ADT 的多种不同的实现;针对每种实现,设计其表示(representation)、表示不变性(rep invariant)、抽象过程(abstraction function)
  5. 使用 OOP 实现 ADT,并判定表示不变性是否违反、各实现是否存在表示泄露(rep exposure);
  6. 测试 ADT 的实现并评估测试的覆盖度;
  7. 使用 ADT 及其实现,为应用问题开发程序;
  8. 在测试代码中,能够写出 testing strategy 并据此设计测试用例。

2.实验环境配置

简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。

特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

Lab1已经配置完成,这里不再赘述。

在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。

git@github.com:ComputerScienceHIT/HIT-Lab2-120L020403.git

3.实验过程

请仔细对照实验手册,针对两个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

3.1.Poetic Walks

在这里简要概述你对该任务的理解。

​​​​​​​3.1.1Get the code and prepare Git repository

如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。

在 Get the code 步骤中,从以下地址获取初始代码:

http://github.com/rainywang/Spring2021_HITCS_SC_Lab2.git

​​​​​​​3.1.2Problem 1: Test Graph <String>

以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。

  1. 使用静态方法的测试策略在文件GrapStaticTest.java中进行测试,主要是测试函数Grap.empty()。由于该方法是静态的,因此只有一个实现,我们只需要运行这些测试一次。代码中原本提供了相应的测试,这里我们先保持原样。
  2. 在测试文件GraphInstanceTest.java中,根据自己编写的testing strategy来实现测试方法,测试包括:addsetremoveverticessourcestargets。对于每一个测试函数需要获得全新的空图,测试设计、实现思路和过程如下。

测试函数

测试设计、实现思路和过程

testAdd( )

往空图中添加新的点、已经存在的点,查看是否add成功。若是add重复的点,返回false。

testSet( )

首先在图中添加进一些点,然后设置有向边,若涉及的顶点存在则直接加入有向边,若不存在则加入顶点后再加入有向边。另外还要考虑加入的有向边是否不小于0,。针对这几点进行测试。

testRemove( )

删除一个顶点,同时要删除将这个顶点作为source或target的那些边。因此除了检查该顶点是否还存在,还要检测相关边是否存在。

testVertices( )

测试加入新的顶点后,顶点集合是否包含这些顶点。

testSourcesAndTargets( )

若有A作为source指向B的边,那么就有B作为target由A来的等权重的边。测试添加边后的某源点或终点的返回值是否预期值相同。

​​​​​​​3.1.3Problem 2: Implement Graph <String>

对于Graph <String>的实现,是基于边和点两种不同的方法来实现的。由此,在实现ConcreteEdgesGraph和ConcreteVerticesGraph之前还需要实现Edge和Vertex两种自定义类。除了实现上述问题中接口Graph的方法,每个方法都需要有documented specification,并实现AF(Abstraction Function)、RI(Representation Invariant)和防止表示暴露,书写checkRep方法以及实现toString方法。

​​​​​​​3.1.3.1Implement ConcreteEdgesGraph

首先要设计Edge类,为其设计了三个私有成员变量,分别代表起点,终点,边权,由于其用private final关键字修饰,所以可以防止表示泄露的问题。

      然后编写了Edge类的AF、RI和防止表示暴露的安全措施:

 

      根据设定的RI设计的checkRep()如下:

      因为Edge是immutable的,所以为其设计了3个get方法,分别用于获取起点,终点以及边权。并且没有设置对其成员变量进行修改的set方法

 

      Edge的toString方法用于输出该边的起点,终点以及边权。输出格式为: Edge:<a,b> weight:5,代表由a指向b,权值为5的边。

       接下来重写ConcreteEdgesGraph类,其AF、RI和防止表示暴露的安全措施如下:

       ConcreteEdgesGraph中有以下两个rep:

 

为了防止表示泄露,在调用各个方法返回之前,使用checkRep方法检查是否有表示泄露的情况出现,具体实现以RI为原则:

 

以下简要阐述ConcreteEdgesGraph类重写的各个方法:

add方法:

       如果顶点集vertices中已经包含所指定的顶点,则返回false,否则将这个顶点加入顶点集合并返回true。

set方法:

       首先判断需要set的边权是否不小于0,若小于零则抛出异常,然后判断涉及的顶点顶点集vertics中是否已经存在,若不存在则加入。再对所有边进行遍历,检查需要set的边newEdge是否已经存在,若存在则先将其remove,然后边权值再与零相比较,若大于0则加入这条边最后返回原来的边权值,若等于零则返回0。若newEdge不存在则直接加入这条边,并返回0。

remove方法:

       判断vertex是否存在若不存在则返回false,若存在则删除边集中与该点相关的边,再将vertex从点集中删除,返回true。

vertices方法:

       返回顶点集合,为防止表示暴露,返回复制后的顶点。

source方法:

       寻找target对应的原点,并将原点与对应的边权以键值对的形式保存在Map中返回。

target方法:

       寻找source对应的原点,并将原点与对应的边权以键值对的形式保存在Map中返回。

toString方法:

       将图的所有信息以字符串形式输出。

​​​​​​​3.1.3.2Implement ConcreteVerticesGraph

首先设计Vertex类,其成员变量如下:

AF、RI和防止表示暴露的安全措施如下:

根据RI设计相应的checkRep()

接下来是为vertex类设计的三个getter

除此之外,vertex是mutable类,所以设计了能够修改vertex的方法:addSource,addTarget,removeSource,removeTarget,四个方法如下:

 

另外对vertex设计了toString方法

接下来设计ConcreteVerticesGraph,以点为核心实现Graph接口

首先设计了一个成员变量保存所有的顶点

设计的AF、RI和防止表示暴露的安全措施如下:

然后根据RI设计相应的checkRep()

 

重写Graph接口各个方法的思路与过程与前面的类似,这里不再赘述

3.1.4Problem 3: Implement generic Graph<L>

3.1.4.1Make the implementations generic

在以上的实现中,都依赖特点标签为特定类型String。在这一步中,我们需要对之前编写的程序进行重构,使得我们的类不依赖于具体的String类,而能适用于任意类型L。

具体的修改方式是将原来代码中的用于表示泛型的String类型替换为泛型的标识符L,并将Edge修改为Edge<L>,Vertex修改为Vertex<L>。

​​​​​​​3.1.4.2Implement Graph.empty()

在Graph.java中将empty的具体实现修改即可,如下图

       更改GraphStaticTest,使用不同泛式,例如基本数据类型(Immutable)中的Double和Integer类型进行检测,增加检测类型代码和结果如下:

 

​​​​​​​3.1.5Problem 4: Poetic walks

任务要求我们实现一个类,利用之前实现的图结构,能够将语料库转化为该种图结构,并且在图中搜索,完成对输入的诗句的句子进行扩充。

3.1.5.1Test GraphPoet

在测试文件GraphPoetTest.java中,根据编写的testing strategy来实现测试前面编写的几个方法,测试包括:corpus类型(nothing、一行、多行、存在空行),input类型(nothing、有无插入),output类型(0/>=1 bridge wordchoose heavier bridge word)。测试设计、实现思路和过程如下:

testExample():

       测试例子test/P1/poet/mugar-omni-theater.txt

testMyExample():

corpus address: test/P1/poet/seven-words.txt

corpus: You are free to add additional methods.

input: I want to add methods.

testEmptyInput():

    corpus address: test/P1/poet/inputNothing.txt

    corpus:Hugo is one of the most popular open-source static site generators.

    With its amazing speed and flexibility, Hugo makes building websites fun again.

    input nothing(无输入)

testEmptyCorpus();

    corpus address: test/P1/poet/corpusNothing.txt

    corpus nothing(无语料库)

input: I want to add methods.

testOneLineTreeOneWord():

    corpus address: test/P1/poet/severalLines.txt

    corpus:

    Hugo is one of the most popular open-source static site generators.

    With its amazing speed and flexibility, Hugo makes building websites fun again.

input: The popular hugo can make websites with amazing speed.

testOneLineTreeSeveralWords():

corpus address: test/P1/poet/corpusToSelf.txt

      corpus: Hello, hello, hello, Hello, my name is Liu Zhou.

   input: I want to add methods.

​​​​​​​3.1.5.2Implement GraphPoet

设计GraphPoet的成员变量:

AF、RI和防止表示暴露的安全措施:

根据RI设计的CheckRep()

在GraphPoet中,我们需要依次实现三个方法:

一.构造方法GraphPoet

在GraphPoet的构造方法中,我们需要读取文本,并由其中语料库按照前文所阐述的方法生成一个单词图。具体实现方式为:输入文件路径并按行读入,将单词进行切分,进行删除标点符号,大写转小写等预处理,每次取相邻元素在图中添加新边。

 

二.生成句子方法Poem

Poem方法输入一个String参数作为原始句子,输出根据单词图匹配过的,扩充了bridge words的新句子。具体实现思路为一次读入两个单词,检索前一个单词子节点的子节点,若其中包含后一个单词,则选择途径通路权重最高的一路,将该路上途径节点表示的单词加入原来两单词之间。

 

三.toString方法

简单重写toString方法,将整个图中所有点的指向转化为一条字符串输出。

 

​​​​​​​3.5.1.3Graph poetry slam

在提供代码的基础上增加一个toString的输出。

 

运行main函数如下输出:

 

​​​​​​​3.6Before you’re done

请按照Problem Set 2: Poetic Walks的说明,检查你的程序。

如何通过Git提交当前版本到GitHub上你的Lab2仓库。

通过IDEA内置的git功能将完成版本上传至个人仓库。

在这里给出你的项目的目录结构树状示意图。

 

​​​​​​​3.2Re-implement the Social Network in Lab1

利用上述实现的ADT,重新实现实验一中的FriendshipGraph,令L泛型为实验一中的Person,改变两个java类,通过本实验中的ConcreteEdgeGraph或者ConcreteVertexGraph来快速实现。

3.2.1FriendshipGraph类

FriendshipGraph类的AF,RI以及防止表示暴露的措施为:

 

在FriendshipGraph类中,实现了如下方法:

构造方法:

 

AddVertex方法:

在图中加入新的人

 

AddEdge方法:

为Person a增加朋友Person b

 

getDistance方法:

计算给定的两个人之间的距离。首先我们需要知道若两个Person对象为同一个,则返回0。然后定义一个Map集合theway和一个Person队列myqueue,队列myqueue用来储存广搜的遍历结果,theway的Map集合用来储存广搜的所有元素及他们与第一个元素的距离。具体实现方法为首先将第一个元素c1入队,并且把第一个元素c1和下标0入集合,当队列非空时,弹出队首元素top,并且得到top在集合theway中的下标distance,然后定义一个Map为friend,执行personGraph.targets(top)得到队首元素的所有朋友的Map,然后定义Set为allfriend,对刚才的friend执行keySet()得到allfriend,只要allfriend中的元素与c2不同,就把这些元素全部入队,并且把这些元素及下标distance+1放入集合。只要队列非空,继续执行以上步骤,直到找到某个元素与c2相同并且返回这个元素在集合theway中的下标。如果直到队列为空还没找到c2,则返回-1:

main():

复制lab1即可。

​​​​​​​3.2.2Person

设计的成员变量:myName保存本人名字,allPerson列表保存所有人的名字

AF、RI和防止表示暴露的措施:

Person实现的方法:

构造方法Person():没有重复名字则加入,构造方法。

getMyname()方法:直接返回本人名字。

 

​​​​​​​3.2.3客户端main()

直接使用Lab1中的main()即可。

 

运行结果:

 

​​​​​​​3.2.4测试用例

测试策略如下:

分别对addVertex,addEdge,getDistance方法进行测试。

addVertextest():

addEdgetest():

getDistancetest();

getallpeopletest():

测试结果如下:

 

​​​​​​​3.2.5​​​​​​​提交至Git仓库

如何通过Git提交当前版本到GitHub上你的Lab2仓库。

通过IDEA内置的git功能将完成版本上传至个人仓库。

在这里给出你的项目的目录结构树状示意图。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值