HIT软件构造Lab1--过程分析

HIT 软件构造Lab1–过程分析

由于实验中要求代码必须是个人完成,所以这里仅提供方法和部分代码。

文章目录

    • HIT 软件构造Lab1--过程分析
    • 1 实验目标概述
    • 2 实验环境配置
    • 3.1 Magic Squares
      • 3.1.1 isLegalMagicSquare()
      • 3.1.2 generateMagicSquare()
    • 3.2 Turtle Graphics
      • 3.2.1 Problem 1: Clone and import
      • 3.2.2 Problem 3: Turtle graphics and drawSquar
      • 3.2.3 Problem 5: Drawing polygons
      • 3.2.4 Problem 6: Calculating Bearings
      • 3.2.5 Problem 7: Convex Hulls
      • 3.2.6 Problem 8: Personal art
    • 3.3 Social Network
      • 3.3.1 设计/实现FriendshipGraph类
      • 3.3.2 设计/实现Person类
      • 3.3.3 设计/实现客户端代码main()
      • 3.3.4 设计/实现测试用例
    • 实验汇总

1 实验目标概述

由于是软件构造第一个实验,该实验并没有着重体现软件构造理念,主要是考察初学者对java编程的熟练程度。以及对于以后要用到的开发工具的熟练使用。

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

2 实验环境配置

开发:采用eclipse工具进行开发。
测试:使用junit4进行单元测试。
运行环境:jdk8。

在Lab0中,实验指导书中已经给出了github仓库的建立绑定,git提交至仓库的方法,下面简要写一下如何将本地代码通过git提交到github远程仓库中。

以本次实验为例,找到要提交的目录
1.查看其路径,这里是 c\users\xuejunqi\Desktop\Lab1
HIT软件构造Lab1--过程分析_第1张图片
2.打开gitbush客户端
3.在命令行输入“git init” 建立本地仓库
4.在命令行输入“cd 路径”
HIT软件构造Lab1--过程分析_第2张图片
5.“git add . ”将文件加入到本地仓库中

在这里插入图片描述
6.“git commit -m "提交信息” "提交文件
在这里插入图片描述
7.“git remote add origin 地址”进行仓库关联
8.“git push -u origin master”即可
在这里插入图片描述

3.1 Magic Squares

该实验是完成幻方矩阵检验,主要考察java基本语法及逻辑结构的使用。

3.1.1 isLegalMagicSquare()

该函数实现判断输入的矩阵是否是幻方矩阵,返回的值为bool型变量。

① 设计过程:该方法要求实现对幻方矩阵的判断,可以说是P1的核心部分。该方法的具体要求是先从一个文本文件中读取矩阵,然后根据换房矩阵的定义判断是否是幻方矩阵。
但是这里有一些特殊情况,因为用户在输入文本文件时,字符之间可能没有使用\t分割,可能矩阵中有非法元素,可能矩阵中有负数或者小数(这里要求矩阵中必须全都是正整数)…要求根据这些不同的情况输出错误信息。
简单来说: 1读取文件 — 2 计算矩阵 ---- 3 对特殊情况判断
② 实现思路:有了上面的设计过程,我们就可以根据制定出实现的方案。对于文件的读取,java中可以用File类,FileReader类和BufferedReader类来实现,想使用这些类,我们就要调用自带的库。如下:

在这里插入图片描述
(这里引入的BufferedWriter和FileWriter和上述相似,是为了将数据写入文件,具体的写操作该方法不要求,下面会阐述)
读完后,接下来就是对数据的处理过程。将数据存入二维数组中然后对二维数组进行计算即可,实现起来并不复杂。
最后就是对特殊情况的处理,我们可以在处理数据的时候进行加以判断,顺便输出错误信息并返回flase。下面来介绍具体的实现过程。
③ 实现过程:对于文件读入,定义了File等类,如下:
在这里插入图片描述
接下来就是读取,读取的过程这里使用readLine(),该方法是以字符串的形式读取,由于后面我们要对读取的数据进行计算,需要转化成整型数据。
这里读入的过程中可以采用多种方式,下面介绍两种:
1.边读取边进行切割,转化。这就要求我们提前定义一个数组,该数组的长度需要我们自己来设置,所以这就可能造成读取的文件超出了数组的界限,所以这里不推荐。
2.读取后再转化,我们可以采用行的读取形式,根据行数确定二维数组的行数,由于二维数组不需要确定列数,这样就可以防止出现越界的情况。具体实现代码如下:

在这里插入图片描述
在这里插入图片描述
line为定义的动态字符串数组,由于动态数组可以自由扩展空间,所以这里采用字符串动态数组。然后对其进行切分,切分后用Integer.valueof()方法将字符串转化成数字。
在这里插入图片描述
这里再转化的时候就会出现了第一个异常,也就是错误信息。我们切分字符串是以“\t”切分,如果字符之间不是用\t,就会导致生成的字符串有空格,转化为整数就抛出异常,这里不提示异常,捕捉到异常就输出错误信息“没用\t分割”,然后退出即可。
在判断幻方矩阵需要计算每一行的和和每一列的和以及两对角线的和,行的和就用sumi[]数组来存储,列的和就用sumj[]来存储,两对角线用sum1和sum2即可。
HIT软件构造Lab1--过程分析_第3张图片
计算后判断是否相等即可,程序并不复杂就不展示全部程序。
对于错误信息的处理,主要处理了如下方面:非正整数元素,没用\t分割,不是方阵,判断的方式如下:
HIT软件构造Lab1--过程分析_第4张图片
④ 实现结果
在这里插入图片描述

3.1.2 generateMagicSquare()

该函数由实验指导书给出主部分,要求我们完成写入文件中以及对输入信息的错误处理即可。

函数设计流程图如下:
HIT软件构造Lab1--过程分析_第5张图片
① 设计实现思路:该过程要求对给定的函数实现相应的写入文件的功能,以及对于特殊情况的错误处理。写文件操作采用Writer类。函数的功能是生成nn的幻方矩阵,生成的思路如上述流程图所示,根据规模n定义nn二维数组,然后进行初始化定义,行序号从0开始,列序号从n/2开始,i定义为1,当i<=n*n时进行循环,每次循环都将当前位置赋值为i,然后进行多种条件判断:
1.当前i是否为规模n的整数倍,如果是,则定位到下一行,同时进行下一次循环。
2.如果不是,则进行判断当前是否是第一行,如果是第一行,定位到最后一行,如果不是第一行,定位到上一行;然后进行第二重判断,列序号是否为最后一列,如果是最后一列,定位到第一列,进行下一次循环;如果不是,定位到下一列,进行下一次循环。
如此循环结束,生成的矩阵即是满足定义的幻方矩阵(注意这里要求n不能为偶数和负数!否则会出现异常)
② 实现过程:简要实现代码如下:
HIT软件构造Lab1--过程分析_第6张图片
这里仅给出了关键部位代码。
③ 实现结果:下面是规模为11的生成矩阵。
HIT软件构造Lab1--过程分析_第7张图片

3.2 Turtle Graphics

该部分完成MIT的作业,实现的是运用简单的函数实现对图的描绘,该部分难点在于Problem7凸包问题。

3.2.1 Problem 1: Clone and import

问题1是对代码的clone和import,从实验指导书中给出的网站下载,并复制到项目目录中即可。

3.2.2 Problem 3: Turtle graphics and drawSquar

画一个简单的正方形。

① 设计实现思路:该过程要求写一个函数,该函数实现画出一个正方形的功能,应用已经提供给我们的turn()和forward()函数。我们知道正方形是4个90°的角,4条长度相等的边。所以这里可以轻松看出来,在画正方形时,只需要前进四次,旋转90°四次即可。
②实现过程
HIT软件构造Lab1--过程分析_第8张图片
③实现结果:输出结果如下
HIT软件构造Lab1--过程分析_第9张图片

3.2.3 Problem 5: Drawing polygons

该问题是在前面的基础上实现绘画一个正多边形。

①设计和实现思路:该过程是实现画出一个正n边形,之前已经编写了一个正n边型的内角函数,根据该函数计算出 n边形的内角,然后旋转180°减去内角的度数即可。
② 实现过程:实现代码如下
HIT软件构造Lab1--过程分析_第10张图片
③ 实现结果:下图为一个正7边形
HIT软件构造Lab1--过程分析_第11张图片

3.2.4 Problem 6: Calculating Bearings

①设计和实现思路:该过程是turn以当前方向为附加参数,计算从当前点到目标点所需的参数。简单说就是从当前点的当前方向,计算需要顺时针转动多少度到达目标点。该函数以当前方向,当前点和目标点三个参数。设计时为了方便,如果当前角度大于360°,就将其减去360°。过程中会使用到math类中的atan2函数,该函数返回的角度是极坐标角度,注意需要将其转化成直角坐标。
还有一个函数calculateBearings,该函数基于上面完成的计算角度的函数,实现一系列点的处理,返回一个角度的List。
②实现过程
HIT软件构造Lab1--过程分析_第12张图片
HIT软件构造Lab1--过程分析_第13张图片
③实现结果:这里直接展示junit4测试的结果
HIT软件构造Lab1--过程分析_第14张图片

3.2.5 Problem 7: Convex Hulls

该部分中的难点,个人水平因素,这个函数改了好久,之前一直在坑中,后来才发现。

①设计和实现思路:该问题个人认为P2中的难点问题,需要比较细致的编程以及多种情况的考虑。该问题实现的是一个凸包函数,给出一系列点,返回出一个位于凸包顶点的Set集合。思路有多种方法,这里采用较为理解的一种,对于凸多边形,我们知道在坐标系中,距离原点最远的点一定是凸多边形的一个顶点。找到了这个点,我们从该点出发,初始角度为0°(沿y轴正方向),旋转一定的角度,我们让旋转后一定碰到一个点,然后保留转动的角度,找出转动角度最小的那个点,那个点一定是凸多边形上的点。
注意这里是凸多边形上的点,不一定是凸多边形的顶点(也就是我们该问题要求解的点)。这个时候就需要进行分类判断,判断该点是否是凸多边形的顶点。下面介绍判断的方法。
如果该点不是顶点,那么一定还有一个旋转角度相同的点,换言之就是如果存在旋转角度相同的点,我们就需要考虑此类特殊情况。我们可以自己画出坐标系,并对这类特殊情况进行分析,并且抛出边上的点即可。
当旋转到初始点的时候,即意味着旋转了一周,也就是形成了凸包,该集合中包括的就是所求的点,这时候退出循环,返回set即可。
②实现过程:找到距离原点最远的点:
HIT软件构造Lab1--过程分析_第15张图片

每次旋转找到旋转角度最小的点:
在这里插入图片描述
对于特殊点的处理,下面是对边是垂直的情况的处理,其他情况类似
HIT软件构造Lab1--过程分析_第16张图片
③实现结果HIT软件构造Lab1--过程分析_第17张图片

3.2.6 Problem 8: Personal art

该部分个人发挥,运用前面多种函数,画出一个较为复杂的图即可。

①设计和实现思路:该部分就是要求设计者自己发挥,画出一个较为复杂的图形,可以运用turn,forward,color等方法。
②实现过程
HIT软件构造Lab1--过程分析_第18张图片
③实现结果HIT软件构造Lab1--过程分析_第19张图片

3.3 Social Network

实现社交网络图,图中两个点最短距离的设计,主要涉及之前学过的数据结构知识。

3.3.1 设计/实现FriendshipGraph类

① 设计和是实现思路:该类是主体,需要定义对象,一个动态列表存放图中的点,然后定义了getdistance函数计算两个人之间的距离。
②实现过程
在这里插入图片描述
该实现了对图中点的保存,采用一个Person类的动态列表。
下面是在图中加入点的方法:
HIT软件构造Lab1--过程分析_第20张图片
由于动态列表有add操作,所以直接加入就可以,如果加入的人的名字与列表中的人名重复,则输出错误信息并退出。
接下来是在图中加入边的信息:
在这里插入图片描述
该方法是调用Person类中加入朋友的方法,由于要求是个有向图的方法,所以这里单向加入朋友。(之前没有注意有向图,双向加入导致与期望值不符)
最后一个方法就是getDistance,该方法实现计算两个人的最短路径,即图的最短路径问题。这里在数据结构中我们已经学习过,所以采用的是广度优先遍历,由于我们出发点是已知的,所以这里用的是一种类似树的层序遍历的方式。从出发点一层一层遍历,第一个找到目标点的时候就返回。
在此之前,如果已知的出发点的朋友圈的大小为0,直接返回相应即可。如果为0,就说明没有朋友,即没有路径,返回-1即可。如果要求该点到该点的距离,直接返回0即可。因为图中没有重复名字的,所以就用两人名字是否相等判断该条件。
在这里插入图片描述
然后就是主要部分,对于不同的两个点之间距离的计算。
在这里插入图片描述
队列记录出栈进栈的点,这是广度优先必须的。访问一个点,然后将该点的临界点全部入队列,队列不为空时,队首出列,访问,如此循环。
这里定义了一个动态数组,存放每一层元素的个数,以及一个Person类的数组,用来存放访问过的点。(之前想在Person类中设置一个visited对象,后来发现这种方法在调用一次getdis之后就会错误,因为此时visited已经设置为1,影响后续结果)。
在这里插入图片描述
接下来就是类似层序遍历,由于从一个已知点出发,将该点邻接点入队并计数,然后计数存入。然后以后每次访问一个点,对应flag记录该层已访问点个数,如果给曾已访问点个数等于该层点数,则层数加1,也就表示路径长度加1。如此循环。
HIT软件构造Lab1--过程分析_第21张图片
如果队列为空还没有找到,则表示不存在路径,返回-1。
③实现结果HIT软件构造Lab1--过程分析_第22张图片

3.3.2 设计/实现Person类

①设计和实现思路:Person类中需要有一个标识个人的信息,即标志,这里就用name来记录。同时将这个变量定义为私有的。除了有name还应该有一个记录朋友的,这里用朋友圈friendzone来表示,同样是私有的。向朋友圈中添加朋友的方法为myfriend。
②实现过程:类中成员的定义
在这里插入图片描述
添加朋友方法的定义:
在这里插入图片描述
同时因为私有变量,还定义了getName和getFriendzone来返回类中成员信息。
③实现结果:由于该类不要求输出等,且定义方法为List基本操作,故不作展示。

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

①设计实现思路:Lab1中给出了测试样例,复制粘贴并按照要求修改输出结果即可。
②实现过程和结果
样例未经修改时的输出结果:1 2 0 -1
HIT软件构造Lab1--过程分析_第23张图片

注释掉第10行结果:-1 -1 0 -1

在这里插入图片描述
将Ross改为Rachel:输入的姓名重复!
在这里插入图片描述

3.3.4 设计/实现测试用例

①设计和实现思路:主要对三个方法进行测试,addVertex(),addEdge(),getDistance()。测试的方法就是向图中加入点和边,然后与已知的一个列表比较是否相等。如果测试距离直接与数进行比较即可。
②实现过程:下面时addVertex的测试,先定义了一个图,然后加入点,再与已知的列表的点比较是否相等。
HIT软件构造Lab1--过程分析_第24张图片
addEdge测试方法与其相似:因为为了测试程序正确,采用了较多的点。
HIT软件构造Lab1--过程分析_第25张图片
接下来是getDistance的测试,针对不同情况的点都进行了测试:

HIT软件构造Lab1--过程分析_第26张图片
③实现结果:这里用Junit4的结果来展示:

HIT软件构造Lab1--过程分析_第27张图片

实验汇总

该实验是软件构造第一次实验,总体实验难度较为简单,涉及java基础较多,是对初学者的一种检验,也方便初学者深化java知识,为今后实验做准备。

你可能感兴趣的:(HIT软件构造Lab1--过程分析)