软件构造lab2

实验环境配置

阅读eclemma官网的安装配置方法,将install按键拖到eclipse的workspace,然后在打开的eclipse marketplace中点击install即可。
在eclipse的workspace中新建java project,其中每一个目录中的文件夹都是source folder(之前不太了解eclipse时使用过folder,发现没有对应功能,必须使用source folder),从github获取代码框架,按照实验手册要求的目录结构完成目录构建。
在我的电脑文件夹中进入eclipse的workspace,在本次实验的project文件夹中右击选择git bash here,在git窗口中完成新建、配置仓库(git init新建仓库)。

实验过程

Poetic Walks

Get the code and prepare Git repository

由于网络问题,使用git clone命令持续报错,我采用了在github直接download压缩包,解压缩后将代码的工程文件夹放入指定目录下的方式获取任务代码。
创建java project,命名为Lab2-学号,在eclipse中配置目录达成实验手册要求。在eclipse的workspace文件夹中,进入Lab2-学号工程文件夹,右键选择GIT Bash here,在GIT Bash中使用git init命令创建空仓库,使用git add将需要的文件夹加入暂存区,使用git commit –m “…”命令来将暂存区的文件进行提交到本地仓库(按照实验手册要求进行分次commit和push),然后使用git remote add origin (我的github仓库地址)配置远程仓库的名称,通过git push origin master来将本地仓库的内容push到远程仓库的master分支上。

Problem 1: Test Graph String

这个问题要求有高覆盖度的Testing strategy。需要经过分析,加上eclemma的数据分析。

Problem 2: Implement Graph

这个问题要求写完两个图(一个用边存储图,一个用顶点存储图),同时完成它们俩的测试用例书写,要借助分析+eclemma工具来尽可能达到高的覆盖度。

Implement ConcreteEdgesGraph
ConcreteEdgesGraph的完善

因为要以边为单位存储图,且要求存储边的自定义类Edge是immutable的,因此将fields都设置成private且final的。当某个边发生修改时,直接删除这个实例,创建新的实例加入边集。
完善了checkRep()函数的书写。
完善了toString()的覆写和spec,打印这个图的顶点数目、所有顶点label、边的数目、所有边的信息(这条边的发出顶点、指向顶点和权值)。
其他函数都按照Graph<L>中的spec来书写即可。
对于自定义类Edge,写了三个函数分别获得这条边的发出顶点、指向顶点和权值。
完善了自定义类Edge的checkRep()函数的书写。在这个class中,只要保证所有存储的边的权值都大于0即可。
完善了自定义类Edge的toString()的覆写和spec,打印这条边的发出顶点、指向顶点和权值。

ConcreteEdgesGraph的测试用例书写

除了GraphInstanceTest之外,还要测试ConcreteEdgesGraph的toString()函数、自定义的Edge类。

Implement ConcreteVerticesGraph
ConcreteVerticesGraph的完善

因为要以顶点为单位存储图,且要求存储边的自定义类Vertex是mutable的,因此将fields都设置成private即可,而不要final(但顶点的label要用final,防止被修改成与其他顶点label相同的情况)。当某个边发生修改时,修改相关的顶点实例信息(修改邻接表)。
完善了checkRep()函数的书写。
完善了toString()的覆写和spec,打印这个图的顶点数目、所有顶点label、边的数目、所有边的信息(这条边的发出顶点、指向顶点和权值)。
其他函数都按照Graph<L>中的spec来书写即可。
对于自定义类Vertex,用一个Map<Vertex, Integer>类型的nextv表示邻接表(表示从这个顶点出发的所有边,存储每个边的指向顶点和权值)。用getNextVertex()函数获取上述邻接表(使用了defensive copy,虽然类型是mutable的,还是使用规定函数来进行修改比较好)。又写了三个函数分别添加、修改、删除邻接表中的一条边。用getLabel()函数获得顶点的label。
完善了自定义类Vertex的checkRep()函数的书写。在这个class中,只要保证所有存储的边的权值都大于0即可。
完善了自定义类Vertex的toString()的覆写和spec,打印这个顶点的label和邻接表边数、每条边的信息(条边的发出顶点、指向顶点和权值)。

ConcreteVerticesGraph的测试用例书写

除了GraphInstanceTest之外,还要测试ConcreteVerticesGraph的toString()函数、自定义的Vertex类。

Problem 3: Implement generic Graph

Make the implementations generic

将String改成L,将类名后面加上<L>。

Implement Graph.empty()

用ConcreteEdgesGraph实例化一个空图然后return。
在GraphStaticTest.java中我添加了Integer和Double类型的图的test。

Problem 4: Poetic walks

使用上面任务所做的图来完成语料库图的构建。这个任务中,要对于输入的语句进行处理,根据空格将字符串分成字符串数组,若两个连续的字符串数组元素tmpname1和tmpname2在语料库图中有对应的路径,且该路径长度为2(中间经过另一个顶点(称为bridge word)),则在这两个字符串元素之间加上该bridge word。当然,如果有多条满足上述条件的路径,选择权值最大的边的bridge word加入。

Test GraphPoet
GraphPoet的String类型构造函数书写

新增构造函数,让GraphPoet能除了使用file,还能直接被输入的String构造出来。

GraphPoetTest的测试用例书写

将语料库放在test/P1/poet/路径下。

Implement GraphPoet

使用BufferReader、FileReader和readLine函数打开、阅读corpus,同时将读进来的语料库用toLowerCase函数转换成小写字母(题目要求对大小写不敏感),利用Graph类的方法,遍历corpus,构建一张语料库图。因为使用的是ConcreteEdgesGraph来表示语料库图,若预备加入的边的两个顶点都存在,再考虑这条边是否存在(因为若没点,必然没边),若边存在则将原边删除、权值加一之后重新加入边。
checkRep函数检查边的权值大于0、没有两条边的发出顶点和指向顶点都一样。
Poem函数把输入的字符串用空格分隔开成为一个字符串数组,然后查找语料库图,若两个连续的字符串数组元素tmpname1和tmpname2在语料库图中有对应的路径,且该路径长度为2(中间经过另一个顶点(称为bridge word)),则在这两个字符串元素之间加上该bridge word。当然,如果有多条满足上述条件的路径,选择权值最大的边的bridge word加入。

Graph poetry slam

对于语料库mugar-omni-theater.txt,输入"Test the system.",输出如下图:
在这里插入图片描述

使用Eclemma检查测试的代码覆盖度

对于Main,无法进行测试。
eclemma测试结果

Before you’re done

先使用git add将需要的目录、文件等从工作区添加到暂存区,然后用git commit –m (注释)将暂存区的文件提交到本地仓库,用git remote add将远程仓库链接存为快捷写法origin,最后用git push origin master将本地仓库推到远程仓库(origin地址处)的master分支下。
目录

Re-implement the Social Network in Lab1

利用p1中完成的Graph类构建表示人际关系的图,每个顶点表示一个人,每条边的权值为1,能添加人、任意两人的人际关系,能计算任意两个人之间的最短距离。

FriendshipGraph类

Fields

用ConcreteEdgesGraph来创建一个空的人际关系图。

方法

该类有5个方法:

构造函数FriendshipGraph()

创建一个空的人际关系图。

addVertex()

将label是tmpname的点加入图的点集。

addEdge()

将label是v1和label是v2的两个点之间的边加入图里。

getDistance()

获得label是v1和label是v2的两个点之间最短路径长度。

main()

main打印一句话来standard out,我选择的是"Perfectly performed",与lab1中一致。

Person类

Fields

用一个字符串来表示label(即人名)。
用一个int类型的marknum来辅助getDistance函数(因为无向图需要用编号辅助进行广度搜索)。

方法

该类有3个方法:

构造函数Person()

创建一个空的人。

getLabel()

获得这个人的label。

覆写equals()

因为ConcreteEdgesGraph中的add方法需要调用equals判断是否相等,就需要给这个类覆写equals。

覆写hashCode()

因为覆写了equals,所以要配套书写hashCode。因为equals判断相等的依据是label相等,因此使用label的hashCode来表示Person类的hashCode即可。

客户端main()

main打印一句话来standard out,我选择的是"Perfectly performed",与lab1中一致。

提交至Git仓库

先使用git add将需要的目录、文件等从工作区添加到暂存区,然后用git commit –m (注释)将暂存区的文件提交到本地仓库,用git remote add将远程仓库链接存为快捷写法origin,最后用git push origin master将本地仓库推到远程仓库(origin地址处)的master分支下。
目录1目录2

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

遇到的难点解决途径
Eclipse报错:The project was not built since its build path is incomplete. Cannot find the class file发现之前一开始下载错了jdk版本,下了jdk15,后来虽然重安了jdk8,但jre还是15,因此重新下载了jre8,重新配置eclipse的jre就解决了。
Eclipse报错:Project ‘项目名’ is missing required source folder: ‘文件名’发现配置目录之前书写的代码,让java project生成了对配置目录前有效的build path,将错误的build path remove即可。
toString输出不符合预期,比预期的字符串开头多了null用于连接(使用+连接)的初始字符串不能初始化为null,而是初始化为" "。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值