HIT-2022软件构造实验二

目录

1.  Poetic Walks

1.1  Get the code and prepare Git repository

1.2  Problem 1: Test Graph

1.3  Problem 2: Implement Graph

1.4  Problem 3: Implement generic Graph

1.5  Problem 4: Poetic walks

1.6  检查测试的代码覆盖度

1.7  Before you’re done

​​​​​​​2.  Re-implement the Social Network in Lab1

​​​​​​​2.1  FriendshipGraph类

​​​​​​​2.2  Person类

​​​​​​​2.3  客户端main()

​​​​​​​2.4  测试用例


1.  Poetic Walks

设计Graph<L>这个ADT,通过逐步实现接口定义的方法完成ADT,首先实现String类型支持的Graph,再将类型拓展到任意类型。

按照接口实现ADT,可以有多种实现方法,而调用时不必关心使用哪种实现。

GraphPoet是Graph实现后的应用,通过调用Graph已经提供给客户端的接口实现GraphPoet。

该实验是逐层递进从实现ADT到应用ADT,同时要求各种注释的编写,训练ADT的实现全流程以及注意事项。

1.1  Get the code and prepare Git repository

Git clone url 获取代码

使用idea的git功能在本地创建仓库,每开始一个任务创建新分支(git branch),完成一阶段提交一次(git commit),完成任务后将master分支和当前分支合并(git merge),再开新分支...

1.2  Problem 1: Test Graph <String>

这一部分需要实现Graph中的静态方法empty,接口需要通过具体类实现。

public static <L> Graph<L> empty() {
        return  new ConcreteEdgesGraph<L>();
    }

1.3  Problem 2: Implement Graph <String>

1.3.1Implement ConcreteEdgesGraph

(1)设计测试方法:

根据Graph所给的方法的描述和限制设计每种方法的测试用例,在GraphInstanceTest中实现。

根据下面分析的Edge的方法设计测试用例,在ConcreteEdgesGraphTest中实现。

(2)设计实现类:

首先通过所给的rep判断该图是由点集以及所有包含的带权有向边的集合组成。

所以容易设计Edge包含起始点、终点、边权,由于Edge是不可变类型,所以只设计三个观察器获取三个属性。Edge设计完成。

接着完成ConcreteEdgesGraph的方法。

Add方法需要注意判断是否已经存在要加的点,Edge实现的图比较好判断,直接在vertices中contains判断即可。

Set方法首先遍历edge中是否已经含有该条边,找到相同的边进行删除或更新操作。没找到就直接添加边。

Remove需要注意判断原先是否存在点,若不存在就可以不用寻找边删除。

Vertices、source、targets方法需要注意防御式拷贝,Set和Map类型都是可变类型,需要使用新创建的对象返回。

ToString按照Source-weight-target,格式表示。

(3)实现完成后执行测试,修改bug直到测试完成。

1.3.2  Implement ConcreteVerticesGraph

(1)设计测试用例:

ConcreteVerticesGraphTest中实现ToString和Vertiex的测试用例。

(2)设计实现类:

ConcreteVerticesGraph只含有Vertex的列表,所以Vertex需要包含边的信息,所以设计为包含自己的标志属性和包含这个点为起点的边的map,记录终点和权值信息。由于map不对客户端开放,所以需要在Vertex内实现对边的查找和更新等操作。

ConcreteVerticesGraph的方法实现和上面的类似。

(3)实现完成后执行测试,修改bug直到测试完成。

1.4  Problem 3: Implement generic Graph<L>

1.4.1  Make the implementations generic

将Graph<String>改为Graph<L>,ConcreteEdgesGraph和ConcreteVerticesGraph后加上<L>,将Edge和Vertex后加上<L>,以及其他函数调用的String换为L。

1.4.2  ​​​​​​​Implement Graph.empty()

同3.1.2。

1.5  Problem 4: Poetic walks

1.5.1  Test GraphPoet

GraphPoet方法测试分类:分别输入错误文件、正确但错误格式文件、正确且格式正确文件。捕获期望错误,正确读入则比较图的边是否符合期望。

Poem方法测试:分别输入可联想的字符串和不可联想的字符串,比对期望。

使用的测试用例easy.txt内容为:Hi hello hi hello everyone.

mugar-omni-theater.txt内容为:This is a test of the Mugar Omni Theater sound system.

​​​​​​​1.5.2  Implement GraphPoet

(1)实现构造函数:

首先使用fileReader和bufferReader读取文件内字符,保存到String变量中,然后使用Scanner的分割按照空格分成一个个单词,两两读入,调用Graph的set方法不断添加边,同时搜索所有已经包含的边,如果已经加入过,将它的边权加一,没有加入则新建一个权值为1的边。

(2)实现Poem:

需要实现两个点之间是否有一个中间点的判断方法searchCenter。在起点的目标点中(调用targets)遍历,每个目标点都查找自己的目标点,如果找到参数的目标点,那么返回该中间点,否则返回空字符串。

之后实现poem就容易了,将输入的字符串按照空格分割,两两单词查找是否有中间点,有就在返回的String里加入该中间点的标签。

​​​​​​​1.5.3  Graph poetry slam

直接运行main,结果为

 

1.6  检查测试的代码覆盖度

使用idea自带run with coverage,得到的数据如下:

 

可以看到三个类都取得了不错的代码覆盖度。

​​​​​​​1.7  Before you’re done

目录结构树状示意图。

 

Git -push提交到Lab2.

​​​​​​​2.  Re-implement the Social Network in Lab1

使用Graph<L>实现RelationShipGraph,将L用Person替换。需要实现Person的equal和hashCode的重写,使得Person可以比较name确认是否同一人,然后Graph其他方法就可以正常调用了。

​​​​​​​2.1  FriendshipGraph

FriendshipGraph包含一个Graph<Person>作为实现的图。

AddVertex调用graph的add方法。

AddEdge调用graph的set方法。

Getdistance使用BFS搜索,创建一个queue添加从起点开始探到的点,每探完一次深度加一,找到则返回深度加一的值,没有找到则返回-1.

​​​​​​​2.2  Person

只有一个name属性,类型为private String。

实现getName方法获取name。

主要重写equal方法,同类型且name相等则返回真。

@Override
    public boolean equals(Object obj) {
        if(!(obj instanceof Person)){
            return false;
        }
        if(obj == this) return true;
        return name.equals(((Person) obj).getName());
    }

同时也要重写hashCode方法,hashCode根据name生成,这样可以保证name相同的同时hashCode也相同。

@Override
    public int hashCode() {
        final int prime = 31;
        int result;
        result = prime + ((name == null)? 0 : name.hashCode());
        return result;
    }

​​​​​​​2.3  客户端main()

按照实验一所给的客户端的代码写main,运行成功。

public static void main(String[] args) {
        FriendshipGraph graph = new FriendshipGraph();
        Person rachel = new Person("Rachel");
        Person ross = new Person("Ross");
        Person ben = new Person("Ben");
        Person kramer = new Person("Kramer");
        graph.addVertex(rachel);
        graph.addVertex(ross);
        graph.addVertex(ben);
        graph.addVertex(kramer);
        graph.addEdge(rachel,ross);
        graph.addEdge(ross,rachel);
        graph.addEdge(ross,ben);
        graph.addEdge(ben,ross);
        graph.addEdge(ben,kramer);
        System.out.println("rachel to ben:"+graph.getDistance(rachel,ben));
        System.out.println("rachel to rachel:"+graph.getDistance(rachel,rachel));
        System.out.println("ben to kramer:"+graph.getDistance(ben,kramer));
        System.out.println("kramer to ben:"+graph.getDistance(kramer,ben));
    }

​​​​​​​2.4  测试用例

addVertex划分:person:空字符串、合法字符串“rachel”和“ross”,重复加入同一字符串“rachel”。
addEdge划分:source,target:空字符串、合法字符串“rachel”“ross”“ben”“kramer”。加入边“rachel-ross”“rachel-ben”“rachel-rachel”,加入重复的边“rachel-ross”。
getDistance:source,target:空字符串、合法字符串“rachel”“ross”“ben”“kramer”,加入边“rachel-ross”“ross-rachel”“ross-ben”“ben-ross”测试在图中的点、不在图中的点,可达(rachel-ben)、不可达(kramer-ben)以及自己到自己(“rachel-rachel”)的距离。

代码覆盖度:(friendship低是因为有main函数)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值