软件构造实验一

1 实验目标概述

本次实验通过求解三个问题,训练基本 Java 编程技能,能够利用 Java OO 开
发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够
为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。
另一方面,利用 Git 作为代码配置管理的工具,学会 Git 的基本使用方法。

  • 基本的 Java OO 编程
  • 基于 Eclipse IDE 进行 Java 编程
  • 基于 JUnit 的测试
  • 基于 Git 的代码配置管理

2 实验环境配置

为了完成本次实验的开发,我安装了eclipse和idea这两个ide,在比较之后,选择了目前主流的idea作为主要的开发工具。Jdk,git则是按照网上的教程学习并且配置好了,jdk的版本与助教的相同,选用了jdk8。在配置juit的时候有点懵,但是多亏了Ide的强大功能,在导入p2的test文件后,对于报错部分按alt+enter就自动装好了junit。至此就是我本次实验的环境配置。
软件构造实验一

3 实验过程

3.1 Magic Squares

这个问题就是给定五个矩阵,然后通过调用5次isLegalmagicsquare这个函数判断那些矩阵是不是magicsquare,同时对于错误的输入报错。同时,generatemagicsquare这个函数能够根据给定的n值,生成一个n阶的magicsquare。
根据实验手册的提示,这个问题总的来说并不难。

3.1.1 isLegalMagicSquare()

首先,我们的矩阵是要从文件中读入的,我采取了输入流的方法
软件构造实验一
在此之后,就能够通过br.readline来一行行获取文件中的信息。
在存储时,我定义了一个二维数组line来存储矩阵
软件构造实验一
然后对于读进来的每一行的信息,用split将其分开,然后调用Integer.Valueof转为数值并判断合法性,如果是则写入矩阵二维数组中,如果不是则返回false。
至此,就把文件中的矩阵读入到程序中的二维数组中了。
接下来要做的事情就很简单了,无非就是几个循环来判断一下行,列,对角线之和是不是相等,如果是就返回true,只要有对不上的,就返回false。
然后在main函数中调用5次这个函数,分别判断给的5的矩阵是不是magicsquare,输出的结果如下:
软件构造实验一

3.1.2 generateMagicSquare()

软件构造实验一
软件构造实验一
同时,根据实验手册要求,对这个函数代码做了适当改进,对一些非法输入进行了检测
软件构造实验一
运行结果:(txt6)
软件构造实验一

3.2 Turtle Graphics

这个问题主要是利用给定的turtle类,进行画图,求凸包,并且通过给定的test。

3.2.1 Problem 1: Clone and import

由于刚开始做实验的时候github时不时抽风,刚好qq群里有人分享,就在qq群中把turtle下载了下来,因为是idea,导入也很简单,打开源文件目录,把P2拖进去后就行了,但是加入工程之后,一片红。解决方案是在pakage前都加上P2.
软件构造实验一
这样就好使了。

3.2.2 Problem 3: Turtle graphics and drawSquare

利用turtle中给出的方法,很简单
软件构造实验一

3.2.3 Problem 5: Drawing polygons

画多边形也很简单,与上面画正方形相比只是多了计算角度的一步
软件构造实验一

3.2.4 Problem 6: Calculating Bearings

首先需要计算还需要旋转的角度
软件构造实验一
对于calculating bearings,就只需要设置循环,然后调用calcuatebearingtopoint就行
软件构造实验一

3.2.5 Problem 7: Convex Hulls

求凸包这块确实麻烦,参考了很多大佬的资料学习
首先凸包的定义简单来说就是找到能包住所有点的凸多边形。比较好的算法有Graham算法,这个算法的思想就是首先对点集进行按照极角坐标的排序,然后找到一个一定在凸包中的点,,一般取最左下的那个点,冰找到一条边。之后就从那条边出发,按照排好的顺序找下一个点,看是需要左转还是右转,如果是左转就压栈继续,如果是右转则弹栈直到构成左转关系,当连起来的时候就形成了一个凸包。
还有一个方法,也是实验手册上推荐的方法,就是礼物盒包装方法,这个算法用一个形象的比喻就是,用一根绳子系好一个点,然后绕大圈,形成的环就是凸包。实现起来主要就是找逆时针第一个碰到的点。
在实际实现的时候,采用了礼物包装算法。因为思想比较简单,画个图就全明白了
具体思路参考注释,
软件构造实验一
软件构造实验一
测试结果:通过
软件构造实验一

3.2.6 Problem 8: Personal art

佛系画了一个
软件构造实验一

3.2.7 Submitting

首先在要提交的文件夹下面右键点开git bash
软件构造实验一
然后依次输入命令即可
软件构造实验一
其中,倒数第二步改成需要提交的仓库地址就可以了。

3.3 Social Network

这个问题说白了就是求无向图中两个顶点间的最短路径。这个上学期在数据结构的课程中学过,并且用c语言写过代码,简单复习了一下实现起来问题不大。就是一开始遵循提示中的用广度优先搜索算法,最后绕了一绕才解决,其实感觉直接用求最短路径的算法比如弗洛伊德算法可能会更加简便。

3.3.1 设计/实现FriendshipGraph类

我是采用邻接矩阵的方式来存储无向图的,因为还没有学会java的指针怎么用。定义的成员变量如下:
软件构造实验一
其中前四个是邻接矩阵的相关变量,后三个则是与后面求最短路径相关的。
其中visited数组表示在广度优先搜索的时候,是否已经访问过,parent数组则存储着在搜索中父节点的下标。
关于加顶点,加边就没什么好说的,就是在加边的时候判断一下输入的合法性就行了
软件构造实验一
软件构造实验一
然后对于求最短路径的方法,首先就是要根据输入的person对象的姓名,找到其在顶点数组中的对应下标,num_ver_ofb, num_ver_ofc,然后则是从输入的第一个person对应的顶点开始,调用广度优先搜索,同时在搜索的同时,记录父节点。搜索完毕之后,根据父节点往上找,就行了。
软件构造实验一

3.3.2 设计/实现Person类

根据需求,我觉得person类只需要包含名字即可
软件构造实验一

3.3.3 设计/实现客户端代码main()

Main函数直接根据实验手册上的来就行,不需要改动
运行结果:
软件构造实验一

3.3.4 设计/实现测试用例

我所用的测试图如下所示
软件构造实验一
根据此图撰写测试代码:
软件构造实验一
这个测试测试了几种随机的情况,并且包含了自己到自己的距离,没有路径两点间的距离这些特殊情况。
测试结果:通过
软件构造实验一