哈工大软件构造Lab1

Lab 1实验报告

1 实验目标概述... 1

2 实验环境配置... 1

3 实验过程... 2

3.1 Magic Squares. 2

3.1.1 isLegalMagicSquare(). 2

3.1.2 generateMagicSquare(). 3

3.2 Turtle Graphics. 5

3.2.1 Problem 1: Clone and import 5

3.2.2 Problem 3: Turtle graphics and drawSquare. 5

3.2.3 Problem 5: Drawing polygons. 6

3.2.4 Problem 6: Calculating Bearings. 7

3.2.5 Problem 7: Convex Hulls. 8

3.2.6 Problem 8: Personal art 9

3.2.7 Submitting. 10

3.3 Social Network. 10

3.3.1 设计/实现FriendshipGraph类... 10

3.3.2 设计/实现Person类... 12

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

3.3.4 设计/实现测试用例... 13

4 实验进度记录... 15

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

6 实验过程中收获的经验、教训、感想... 16

6.1 实验过程中收获的经验和教训... 16

6.2 针对以下方面的感受... 16

 

 

  1. 实验目标概述

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

⚫ 基本的 Java OO 编程

⚫ 基于 Eclipse IDE 进行 Java 编程

⚫ 基于 JUnit 的测试

⚫ 基于 Git 的代码配置管理。

  1. 实验环境配置

在官网下载安装JDK,根据网上的步骤配置环境变量。

在官网下载安装Eclipse,设置JRE以及其他preferences。新建一个Workspace,建立项目、包以及java源代码,Eclipse配置成功的结果如图。

在官网下载Git并安装,设置用户名、邮箱等信息,Git配置成功的结果如图。

GitHub Lab1仓库的URL地址:https://github.com/ComputerScienceHIT/HIT-Lab1-1190200817。

  1. 实验过程

请仔细对照实验手册,针对四个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但无需把你的源代码全部粘贴过来!)。

为了条理清晰,可根据需要在各节增加三级标题。

    1. Magic Squares

主要任务:从txt文件中解析数据,并判断数据是否构成一个幻方,通过5个文件进行测试。同时阅读和改进产生幻方的代码,并进行测试。

      1. isLegalMagicSquare()

首先,需要从txt文件中读出数据,读txt文件可以使用固定的格式,即使用BufferedReader并用try-resource语句处理异常。

   

利用BufferedReader,每次可以从文件中读入一行字符串。由于txt文件以’\t’分隔数据的,用String类的split方法可以将读入的字符串以’\t’分隔,得到字符串数组,每个字符串数组都代表一个数。使用Integer.valueOf将分隔后的每个字符串解析为数字,同时需要捕获异常识别非法数据。

所有数据都存在二维ArrayList中,获得每一行数据的个数以及总行数,判断是否为n*n的矩阵。分别计算每行、每列以及两个对角线上的数字之和,比较是否相等,并返回结果。如果出现各种特殊情况,输出错误提示信息并返回。

      1. generateMagicSquare()

阅读generateMagicSquare()的代码,可以看出它是将1到n2  填充到一个n*n  的幻方中,这种方法是常用的填充幻方的方法。程序的流程图如下:

但是,这种方法只能填充n  为奇数时的幻方。当n  为偶数时,函数产生异常java.lang.ArrayIndexOutOfBoundsException即填充过程中在row++时发生数组越界访问。并且当n  是负数时,不能有效处理非法输入,产生异常java.lang.NegativeArraySizeException即初始化了行列数为负数的数组。这导致了很差的健壮性。修改这个函数,当输入不合法时提示错误并退出。

同时,当输入合法时,增加将结果写入文件的功能。和之前类似,使用BufferedWriter将数据写入文件。

利用前面的 isLegalMagicSquare()函数,可以判断生成的文本文件确实符合 Magic Square。

    1. Turtle Graphics

主要任务:根据函数的注释补全代码,实现一系列绘图可能用到的功能。包括画出正方形、计算正多边形的内角、计算对应内角的正多边形边数、计算绘图时的角度转移、计算凸包、以及绘制自己独特的图形。

      1. Problem 1: Clone and import

使用git init初始化一个本地仓库,通过git clone将GitHub上的文件下载到这个仓库中。这时就可以利用IDE进行代码编写。每当认为某一个代码改进完成,可以让它成为一个新的版本时,利用git add添加相应代码,使用git commit将本地文件加入到本地仓库。当所有的代码都修改完毕,通过git push origin master将本地仓库push到GitHub上。

      1. Problem 3: Turtle graphics and drawSquare

绘制图形时要用到两个函数:forward和turn,分别实现前进和转向。绘制正方形时,只需要每次前进给定长度,然后转向90°,循环四次即可。

代码:

结果:

 

      1. Problem 5: Drawing polygons

对于给定边数的正多边形,需要计算内角的度数来确定每次转向的度数。实现calculateRegularPolygonAngle()函数确定给定边数的正多边形的内角度数。直接通过公式可求出。

和上面一样,每次前进给定长度,转向的角度为外角的度数,循环次数为边数。

代码:

结果(以正六边形为例):

最后还要实现给定内角度数,确定正多边形边数的函数。直接通过公式可求出。注意最后要将结果四舍五入才能返回整数。

      1. Problem 6: Calculating Bearings

实现函数calculateBearingToPoint()以满足已知起点、终点和当前朝向时,应该转向的角度。计算起点和终点所连直线的斜率,利用atan函数得到最终的朝向的角度,它和当前朝向的差值就是需要转过的角度。

通过调用calculateBearingToPoint()函数就可以计算经过一系列点时每次要转向的角度,进而实现calculateBearings()。已知初始朝向,按顺序在列表中取出两个点,调用calculateBearingToPoint()就可以得到这两个点之间需要转过的角。修改当前朝向为转向之后的角度,就可以进行下一次计算。需要注意,更新当前朝向后,如果角度超过360°,需要减去360°。

      1. Problem 7: Convex Hulls

使用安德鲁算法求解凸包。首先判断特殊情况,如果顶点数小于等于2时,这些点都会是凸包中的,直接返回原点集。找到所有点中横坐标最大的点,有多个则选择纵坐标最小的点,把它作为基准点,这个点一定在凸包中。其他的点和这个点的连线与y轴正半轴存在夹角,按照夹角从小到大对其他顶点排序。维护一个栈,首先将基准点入栈。按顺序从排好序的顶点中取出一个,如果栈中的点数大于2,就取出栈顶的两个点。通过计算向量的内积判断栈顶的点是否应该在凸包中,如果不在,将栈顶的点弹出,继续判断;如果在,将取出的顶点入栈。如果栈中的点数小于2,直接将取出的顶点入栈。最后,栈中的点就是凸包中的点。代码如下:

     

对于以上实现的代码,都通过了测试程序的测试。

      1. Problem 8: Personal art

利用while循环绘制一个雪花图形,通过递推确定每次要转向的角度。

代码:

结果:

      1. Submitting

当所有代码都修改完成并确认无误后,利用git add添加修改过的代码文件,使用git commit将本地文件加入到本地仓库,同时可以标注版本信息。通过git push origin master将本地仓库push到GitHub上,在GitHub上可以看到push之后的文件。

    1. Social Network

主要任务:设计Person类和FriendshipGraph类来模拟一个社交网络,并实现社交网络中需要的一些简单功能,包括添加人、添加社交关系以及计算两个人之间的距离。同时,编写测试程序来检查实现的正确性。

      1. 设计/实现FriendshipGraph类

社交网络是一个图模型,FriendshipGraph类中要存储一个图,并且要支持各种功能。我在FriendshipGraph类中只存储图的顶点,而顶点之间的关系和某一个人有关,因此存储在Person类中。FriendshipGraph类的属性只有private HashSet<Person> vertex用来存储图的顶点,方法包括构造方法、private变量的getter和setter以及一些简单的功能addVertex(),addEdge(),getDistance()。另外,由于名字是Person的属性,因此判断名字是否重复交给Person类实现。

addVertex()向vertex集合中添加顶点,addEdge()在Person类的朋友集合中添加新的朋友,getDistance()利用广度优先搜索计算两个Person之间的最近距离。同时,在函数中判断一些非法情况。具体代码如下:

属性

构造函数

getter和setter

addVertex()

addEdge()

getDistance()

      1. 设计/实现Person类

Person类是对人的抽象,属性包括自己的名字和朋友集合。方法包括:内部private属性的getter和setter,构造函数,以及添加朋友的addFriend()。同时,为了判断重名,在Person类中重写hashCode()、equals()和toString()方法,使得每个Person实例有不同的名字,如果有两个同名Person添加到社交网络的集合中,集合只会保留一个。具体代码如下:

属性

addFrined()

构造函数

Getter和setter

重写的hashCode,equals,toString

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

按照给定的客户端代码实现。

      1. 设计/实现测试用例

对于addVertex()的测试:当调用addVertex()后,测试FriendshipGraph类中顶点集合vertex的大小。如果添加的人不重复,大小会加一,否则不变。

当addVertex()添加人的名字重复时,程序会输出提示信息并退出。因此测试程序退出时的输出内容是否正确(在网上查阅资料得知,需要添加额外的代码以测试调用System.exit()的情况)。

   

对于addEdge()的测试:当调用addEdge()后,测试添加朋友的Person类中朋友集合friend的大小。addEdge()两个参数对应的Person类中的friend集合大小都会加一。

对于getDistance()的测试:建立一个社交网络,测试函数返回的结果和实际结果是否相同,需要覆盖距离是-1、0以及大于0的情况。

测试结果:

  1. 实验进度记录

 

日期

时间段

任务

实际完成情况

2021-05-06

20:30-21:30

编写Social Network问题中的FriendshipGraph类和Person类并在main函数中进行测试

按计划完成

2021-05-07

18:30-19:30

编写isLegalMagicSquare()函数,并用1.txt~5.txt文件中的数据进行测试

延期10分钟完成

2021-05-07

20:30-21:30

分析generateMagicSquare()函数的功能并进行修改,用其产生的Magic Square测试isLegalMagicSquare()函数

按计划完成

2021-05-08

14:00-17:00

完成Turtle Graphics问题中的所有任务

按计划完成

2021-05-09

18:30-19:00

设计并编写addVertex(),addEdge()和getDistance()的单元测试

按计划完成

2021-05-11

13:45-15:00

使用Git管理仓库并push到GitHub

延期20分钟完成

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

遇到的困难

解决途径

用Git管理时无法合并到master分支

 

查阅资料,发现命令行参数存在问题,修改后成功。

  1. 实验过程中收获的经验、教训、感想
    1. 实验过程中收获的经验和教训

本次实验初次接触软件构造,在实验中,我明白了软件构造的基本流程,并且更加熟练地掌握Java语言。同时,对Git的学习和使用也让我懂得了软件管理的重要性。获得了一些使用Git和本地IDE进行软件构造的经验。同时,也获得了一些教训,一定要在编写代码之前考虑好类的构造,属性、方法的定义以及使用的数据结构,否则一旦出错可能需要重头再来;同时,在设计之前也要平衡不同的质量目标,不至于在代码编写结束后再耗费很大功夫重新修改。

    1. 针对以下方面的感受
  1. Java编程语言是否对你的口味?

是,面向对象的语言会更容易编写,同时Java也包含了更多常用的数据 结构和函数,可以节省编写代码的工作量。

  1. 关于Eclipse IDE;

Eclipse集成开发环境功能很强大,使得编写程序更加容易。

  1. 关于Git和GitHub;

虽然Git的指令有些难搞懂,但是用它管理项目是很方便的。GitHub上的资源很多,功能也很强,但就是访问速度太慢了。

  1. 关于CMU和MIT的作业;

难度适合,也让我们可以与国外名校接轨。

  1. 关于本实验的工作量、难度、deadline;

难度不大,但是工作有些繁琐,但deadline设置比较合理,可以按时完成。

  1. 关于初接触“软件构造”课程;

初次做软件构造的实验,我认为可以通过这个课程提升自己的编程能力并且培养一种全局观念,同时可以获得更多不同的能力。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值