比第一次难多了。
目录
3.1.1 Get the code and prepare Git repository· 2
3.1.2 Problem 1: Test Graph <String>· 3
3.1.3 Problem 2: Implement Graph <String>· 5
3.1.3.1 Implement ConcreteEdgesGraph· 6
3.1.3.2 Implement ConcreteVerticesGraph· 8
3.1.4 Problem 3: Implement generic Graph<L>· 10
3.1.4.1 Make the implementations generic· 11
3.1.4.2 Implement Graph.empty()· 11
3.1.5 Problem 4: Poetic walks· 11
3.1.5.2 Implement GraphPoet· 12
3.1.5.3 Graph poetry slam·· 13
本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象
编程(OOP)技术实现 ADT。具体来说:
针对给定的应用问题,从问题描述中识别所需的 ADT;
设计 ADT 规约(pre-condition、post-condition)并评估规约的质量;
根据 ADT 的规约设计测试用例;
ADT 的泛型化;
根据规约设计 ADT 的多种不同的实现;针对每种实现,设计其表示(representation)、表示不变性(rep invariant)、抽象过程(abstractionfunction)
使用 OOP 实现 ADT,并判定表示不变性是否违反、各实现是否存在表
示泄露(rep exposure);
测试 ADT 的实现并评估测试的覆盖度;
使用 ADT 及其实现,为应用问题开发程序;
在测试代码中,能够写出 testing strategy 并据此设计测试用例。
Windos10专业版,IDEA,jdk-11,Junit4.
注册GitHub账号,并且授权GitHub classroom,获取lab2的GitHub classroom的URL地址。
Git代码配置管理。首先安装最新版Git,获取个人GitHub的URL地址,通过在Git bash输入指令建立管理本地仓库,将文件push到远程仓库。
困难:
IDEA中含有自带的代码覆盖度插件,但是在使用前需要配置,一开始没有进行配置,所以一直无法显示覆盖率。
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/HIT-Lab2-120L021923.git
请仔细对照实验手册,针对两个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
主要目的是测试 ADT 的规约设计和 ADT 的多种不同的实现,并练习 TDD 测试优先编程的编程习,在后面练习 ADT 的泛型化。
首先分别构造两个实例类的rep类Vertex和Edge;
然后用String作为L的特例,分别在两个实例类中实现Graph接口中的各个方法,写对应的test文件以确保其正确性,并且按照要求撰写每个方法的规约,AF,RI,以及rep exposure;
然后将所有String变量替换为泛型L,实现图的泛型化。
然后对给定的文本文件,按照给定规则建立有向图,调用Graph作为存储语料库的数据结构,利用该结构,对输入的字符串进行扩充。
如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。
获取初始代码:
https://github.com/rainywang/Spring2020_HITCS_SC_Lab2/tree/master/P1
在作业描述中若遇到 “commit and push”的要求 请将你的代码push到你的 GitHub Lab2仓库中。具体步骤为:
Git init
Git remote add origin xxxx你的github的地址
Git pull origin master
Git add .
Git commit -m “xxx”
Git push origin master
-
-
- Problem 1: Test Graph <String>
-
以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。
测试策略:
‘
以下均为抽象的测试方法类
Add方法:
Set方法:
与remove一同进行测试
Remove方法:
Vertices方法:
Source方法:
Target方法:
-
-
- Problem 2: Implement Graph <String>
-
以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。
-
-
-
- Implement ConcreteEdgesGraph
-
-
1.首先要实现edge类:
策略:
Fields:
Function:
public L getSource()
public L getTarget()
public int getWeight()
获取信息
public boolean equals(Edge<L> edge)
public int hashcode()
重写equals
public String toString()
实现图形化
Checkrep:
2.在edge类的基础上实现ConcreteEdgesGraph类
策略:
函数及其思路:
public boolean add(L vertex)
调用List.add,添加成功返回true,list中已有返回false
public int set(L source, L target, int weight)
检查输入满足weight>=0。当weight<0时,如果当前没有该edge,则直接添加,返回值为0,如果已经有该edge,则记录旧值,修改为新值。如果weight==0,当删除的边不存在时返回0,当存在时,删除该节点,该边,如果此时两端点之中没有边与之相连了则删除节点。
public boolean remove(L vertex)
首先检查vertex是否在vertices内。若存在,则遍历检查有没有与之相连的边,全部删除。
public Set<L> vertices()
返回vertices
public Map<L, Integer> sources(L target)
在edges中寻找所有目标点是target的初始节点
public Map<L, Integer> targets(L source)
在edges中寻找所有目标点是sourse的初始节点
全部通过
-
-
-
- Implement ConcreteVerticesGraph
-
-
1.首先实现Vertex类:
策略:
Fields:
Function:
public L getSource()
public L getTargets()
public int getName()
获取信息
public int setSource(L source, int weight)
public int setTarget(L target, int weight)
设置source与target
public String toString()
实现图形化
Checkrep:
防御性编程
2.然后在vertex类的基础上完成ConcreteVerticesGraph类:
函数及其思路:
public boolean add(L vertex)
调用List.add,添加成功返回true,list中已有返回false
public int set(L source, L target, int weight)
如果存在vertices()中找到source,使用findVertex返回对应index,从而找到源点,否则以source为string创建一个新的源点,并将它添加进vertices。对于target操作同理。
得到源点和目标点后,分别对目标点调用setSource,源点调用setTarget即可。
public boolean remove(String vertex)
如果vertices()不包含vertex,返回false。否则遍历所有点,如果某点和vertex存在映射关系,则将这种关系删除。最后将vertex对应的点从vertices中删除即可。
public Set<String> vertices()
遍历vertices,找到每个点对应的string,添加进set即可。
public Map<String, Integer> sources(String target)
如果找不到target对应的点,返回Collections.emptyMap()。否则调用getOneSource返回target对应的源点图。
public Map<String, Integer> targets(String source)
如果找不到source对应的点,返回Collections.emptyMap()。否则调用getOneTarget返回source对应的目标点图。
public String toString()
graph空,则返回“An Empty Graph”.
graph不为空,则将每个点的toString连接起来
全部通过。
-
-
- Problem 3: Implement generic Graph<L>
-
将已有的两个 Graph的实现改为Graph的泛型实现。
更改类名:
public class ConcreteEdgesGraph<L> implements Graph<L>
public class ConcreteVerticesGraph<L> implements Graph<L>
并修改有关的String为泛型L
将ConcreteEdgesGraph和ConcreteVerticesGraph都用泛型实现后,重新跑测试
全部通过。
-
-
-
- Implement Graph.empty()
-
-
选择ConcreteEdgesGraph 作为返回对象实现Graph.empty()函数:
-
-
- Problem 4: Poetic walks
- Test GraphPoet
- Problem 4: Poetic walks
-
-
-
-
- Implement GraphPoet
-
-
实现:
public GraphPoet(File corpus) throws IOException
先读文件,并把文件中的单词存在words中。使用BufferedReader读取文本文件中的数据,类Scanner用于将输入的文本分解成多个部分。
然后调用Graph类中的方法,将单词转化为图,添加顶点,set边,其中权值全部设置为1.
public String poem(String input)
遍历input中所有单词,调用Graph.targets()和Graph.sources()方法。如果该单词的targets和后面一个单词的sources有交集,则添加一条bridge,并且在两个单词的bridge中随机选择一个插入到字符串中。
public String toString()
调用Graph.tostring()方法。
请按照Problem Set 2: Poetic Walks的说明,检查你的程序。
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
在这里给出你的项目的目录结构树状示意图。
在这里简要概述你对该任务的理解。
这个实验是基于在Poetic Walks中定义的Graph及其两种实现,重新实现Lab1中的 FriendshipGraph类。我们需要尽可能复用ConcreteEdgesGraph或 ConcreteVerticesGraph中已经实现的add()和set()方法,而不是从零开始。另外基于所选定的 ConcreteEdgesGraph 或 ConcreteVerticesGraph的rep来实现,而不能修改父类的rep。
public boolean addVertex(Person a)
遍历父类的vertices(),如果存在一个元素的name域与Person的name域相等,证明这个点已经存在,输出提示并结束程序,否则调用父类的add(a)将该点加入。
public void addEdge(Person a1, Person a2)
判断点是否存在,若存在直接加上边即可
public int getDistance(Person a1,Person a2)
使用BFS算法求a1与a2之间的最短距离,BFS需要遍历邻居节点时调用父类接口的targets(a1)就可以获得a1的所有邻居节点。
改为private+final,提高安全性。
除此以外与lab1几乎一样。
-
-
- 客户端main()
-
public static void main(String Args[])与lab1相同。
-
-
- 提交至Git仓库
-
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
在这里给出你的项目的目录结构树状示意图。