哈工大软件构造实验一实验报告

2020年春季学期
计算机学院《软件构造》课程

 

 

 

 

Lab 1实验报告
 

 

 

 

 

 

 

 

 

姓名

赵俊

学号

1180300508

班号

1836101

电子邮件

[email protected]

手机号码

18785943479

 

 

 

目录

 

1 实验目标概述... 1

2 实验环境配置... 1

3 实验过程... 1

3.1 Magic Squares. 1

3.1.1 isLegalMagicSquare(). 1

3.1.2 generateMagicSquare(). 1

3.2 Turtle Graphics. 1

3.2.1 Problem 1: Clone and import 2

3.2.2 Problem 3: Turtle graphics and drawSquare. 2

3.2.3 Problem 5: Drawing polygons. 2

3.2.4 Problem 6: Calculating Bearings. 2

3.2.5 Problem 7: Convex Hulls. 2

3.2.6 Problem 8: Personal art 2

3.2.7 Submitting. 2

3.3 Social Network. 2

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

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

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

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

4 实验进度记录... 3

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

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

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

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

 

 

  1. 实验目标概述

这次实验通过解决求解三个问题,训练基本的Java编程技能,并且培养阅读已有的代码框架并且根据需求补全代码的能力,能够为所开发的代码编写基本的测试程序并完成测试。学会使用GIT。

  1. 实验环境配置

简要陈述你配置本次实验所需开发、测试、运行环境的过程,必要时可以给出屏幕截图。

特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

到java官网以及eclipse官网下载了jdk以及eclipse,并根据菜鸟教程配置了环境。在下载git时怎么也下不了,后来发现360软件管家下得超快,嘻嘻。

下载好git后随便在一个文件夹空白处git bash here

输入如图命令即配置完成

 

在这里给出你的GitHub Lab1仓库的URL地址(Lab1-学号)。

https://github.com/ComputerScienceHIT/Lab1-1180300508

  1. 实验过程

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

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

    1. Magic Squares

对于输入的n*n矩阵,判断它是否是一个幻方(由n*n个数字构成的正方形,要求每行、每列、对角线数字和相同)。

      1. isLegalMagicSquare()

1读取文件,用二维数组储存读入的数据

       首先利用FileReader与BufferedReader对象读取文件,然后对每一行判断是否含有非法字符(不是0~9或者分隔符‘\t’),若非法,返回false,否则利用String.split(‘\t’)方法取出矩阵的数字用二维数组保存。

2判断是否满足幻方定义

对于存好的矩阵,行列不相等返回false,否则对每列每行对角线分别求和,都一致才返回true,否则返回false。

      1. generateMagicSquare()

1模拟

按照代码模拟了一遍,发现这样可以构造任何一个正奇数阶幻方上网查了一下,这种构造方法名叫德拉鲁布(De laloubere)算法,可以构造任何一个正奇数阶幻方,有一个口诀:1坐边中间,斜着把数填。出边填对面,偶数往下旋。出角仅一次,转回下格间。

如下图可以看到一个5阶幻方如何构造:

17   24   1     8     15

23   5     7     14   16

4     6     13   20   22

10   12   19   21   3

11   18   25   2     9

 

2异常处理

对于输入的矩阵的边长是偶数或负数,就返回false即可。

 

3写入文件

调用FileWriter对象以及FileWriter.write(magic[row][col] + ‘\t’)方法即可将生成的矩阵写入到6.txt文本中。

4附上流程图

    1. Turtle Graphics

完善TurtleSoup.java文件,这个实验是为了训练使用java自带的画图库。

      1. Problem 1: Clone and import

如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。    

 

在要建立仓库的文件夹右键单击空白处,点击Git bash here打开git命令行界面

①获取代码

使用git clonehttps://github.com/rainywang/Spring2020_HITCS_SC_Lab1.git指令即可获取该任务代码

②建立仓库

使用git init命令在一个空文件夹建立仓库

接下来用git add xxx、git commit -m “xxx”等命令可以在本地仓库添加本地的开发项目

      1. Problem 3: Turtle graphics and drawSquare

这个问题要求我们完成drawSquare函数,这个问题很简单,将给出的边长利用在turtle.forward方法中,表示前进的长度,然后每次转90度,循环4次即可画出一个正方形。

      1. Problem 5: Drawing polygons

double calculateRegularPolygonAngle(int sides);

要求:

       这个方法是根据正多边形的边数计算出多边形的内角

注意:

       注意边数大于2即可

算法要点:

公式是double angle = 360 – 180/sides;

int calculatePolygonSidesFromAngle(double angle);

要求:

       这个方法是根据正多边形的内角计算出边数

注意:

       注意角度范围为0~360;

算法要点:

公式是int sides = Math.rint(180/(360 – angle));

void drawRegularPolygon(Turtle turtle, int sides, int sideLength);

要求:

       这个方法是根据给定的多边形边数与边长画出一个正多边形

注意:

       注意边数大于2,边长大于0

算法要点:

       需要调用calculateRegularPolygonAngle(int sides)函数得到角度,循环画边即可

      1. Problem 6: Calculating Bearings

double calculateBearingToPoint(double currentBearing, int currentX, int currentY, int targetX, int targetY) ;

要求:

 

这个方法要求用给定的参数求出从当前方向转到target点与current点连线顺时针需要旋转的角度。

注意:

       将角度都化为[0,360)可以更简便地进行计算

算法要点:

一个合理的算法是以x轴为极轴,current点为极点建立极坐标轴,然后利用Math.atan2(y,x)函数计算出target点与current点连线与x轴的夹角(极角),并将currenBearing与求得的极角转化为>=0且<360°,从而得到它们的差,即为所求

②List<Double> calculateBearings(List<Integer> xCoords, List<Integer> yCoords);

       要求:

根据参数计算出每次要旋转的角度

注意:

X列表元素个数要与y列表元素个数相等

算法要点:

以第一次向北,接下来每一次都根据前一次的角度以及当前点与前一点的连线极角(极点为前一点)来计算,返回角度列表即可

      1. Problem 7: Convex Hulls

①Set<Point> convexHull(Set<Point> points);

要求:

解凸包问题

注意:

points集合为空时返回一个空的convexHull点集

算法要点:

使用gramham扫描法

1.首先在points中找出一个对照点,放入到栈中,这个对照点就是在点集的最下,最左的那个点,这个点为极点,极轴平行于x轴建立极坐标轴。

2.对剩下的点按相对于对照点的极角从小到大排序,

特殊情况:

如果横坐标与极点相同,按纵坐标从大到小排序

如果纵坐标与极点相同,按横坐标从小到大排序

3.把输入的点集的前两个点放入到栈中,然后依次扫描剩余的点,把不是凸包顶点的点从栈中剔除,沿逆时针方向通过凸包时,在每个顶点处应该左转,因此,如果发现在顶点处没有左转,就可以从栈里弹出了,把向左转的点加入到栈中

最后栈里面保存的就是凸包的顶点,将这个栈的内容全都添加到convexHull集合中即可

 

double calculatePolarAngle(double deltaY, double deltaX);

       这是本人自己添加的一个函数,它返回极角angle(0 <= angle < 360)

      1. Problem 8: Personal art

本人利用龟图画了一个8层颜色的六边形,oh yeah

      1. Submitting

如何通过Git提交当前版本到GitHub上你的Lab1仓库。

①将文件复制到.git的父目录下,在git bash 使用git add、git commit -m命令

②接着使用git remote add origin https://github.com/ComputerScienceHIT/Lab1-1180300508/tree/master.git命令连接到远程仓库

③使用git pull origin master --allow-unrelated-histories命令将本地仓库与远程仓库强行合并(前提是文件不冲突)

④使用git push -u origin master命令将本地仓库push到远程仓库上即可

    1. Social Network

在人群中通过关系将他们连接起来,要求设计一个关于人际关系网的功能,能在人群中添加新的人,能在人群中指定的某两个人之间建立关系,并能实现指定某两个人的关系长度

      1. 设计/实现FriendshipGraph类

思路:使用vector二维数组矩阵来存储图,按照被添加先后顺序,用序号代表被添加的人名顶点。

设计:在图矩阵map中,-1表示不可达,0表示自身到达自身的距离,大于0的数表示两个顶点间的距离。使用bfs算法求得两个顶点间的距离。

具体函数:

1addvertex函数:需要注意的是重复添加人名要返回错误信息;在此函数中扩展人名列表;图的矩阵要扩展,新的一列和新的一行除了对角线为0,其他全为-1。

2addEdge函数:需要注意自身不能与自身建边;两个人重复建边以最新的为准;不能与不存在的人建边。

3getDistance函数:需要用bfs(宽度优先搜索)来对两个人之间求距离,注意与不存在的人之间距离为-1;不可达的两个人之间距离为-1;自身到达自身距离为0;

      1. 设计/实现Person类

设计和实现思路:Person类其实是创建一个人名对象,只需要保存人名字符串即可

如图:

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

实验手册上已经给出了代码

      1. 设计/实现测试用例

测试设计:

1对于addvertex函数要测试正常添加一个人(true)与重复添加一个人(false);

2对于addEdge函数要测试两个人正常建立关系(true)、一个人与自己建立关系(false)、两个人重复建立关系(以最新关系为准)、不存在的人名(false);

3对于getDistance函数要测试不可达关系、自身到达自身的距离、一个可达关系的距离、不存在的人名(false)。

  1. 实验进度记录

请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。

每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。

不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。

日期

时间段

任务

实际完成情况

2020-03-02

15:30-16:30

编写第一个java程序(helloworld)

按计划完成

2020-03-02

17:00-18:00

编写问题1的isLegalMagicSquare函数并进行测试

遇到困难,未完成(不会读入文件)

2020-03-02

22:00-23:00

学习java使用相对路径读取文件

按计划完成

2020-03-03

18:30-21:00

编写问题1的isLegalMagicSquare函数并进行测试

延期半小时完成

2020-03-04

21:30-22:30

测试问题1的generateMagicSquare函数

遇到困难,未完成(不会写入文件)

2020-03-05

20:30-22:00

测试问题1的generateMagicSquare函数并添加异常处理以及写入文件功能

延期半小时完成

2020-03-08

18:30-19:30

编写问题3的addEdge函数和addVertex函数并进行测试

按计划完成

2020-03-09

15;30-18:30

编写问题3的getDistance函数

遇到困难,未完成

2020-03-10

18:00-19:00

继续编写问题3的getDistance函数

延期半小时完成

2020-03-10

19:30-20:30

测试问题3的addEdge,addVertex和getDistance函数

遇到困难,未完成

2020-03-10

22:00-23:30

测试问题3的addEdge,addVertex和getDistance函数

延期半小时完成

2020-03-11

20:00-22:00

修改问题3的FriendGraph类使用边长数组vector

按计划完成

2020-03-12

20:00-22:00

修改问题3的FriendGraph类抛出异常与FriendGraphTest测试类

按计划完成

2020-03-13

11:00-12:00

编写并测试问题2的turtleSoup类的drawSquare、calculateRegularPolygonAngle、calculatePolygonSidesFromAngle函数

遇到困难,未完成

2020-03-13

20:30-22:30

编写并测试问题2的turtleSoup类的calculatePolygonSidesFromAngle、drawRegularPolygon、

calculateBearingToPoint、calculateBearings函数

按计划完成

2020-03-14

12:30-17.30

编写并测试问题2的convexHull凸包问题算法

延期一个小时完成

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

遇到的困难

解决途径

不会java

不会java读取文件以及提取字符串中的整数

 

到菜鸟教程学习java语法

学习FileReader与BufferReader类以及String.split()方法的用法

Eclipse不会用

Eclipse没有代码提示功能

Eclipse报错找不到主类路径

到csdn查找用法

寻找如何配置eclipse

删除了原来的文件,重新创建

使用git命令时遇到各种错误

 

 

 

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

①Collections.sort(List<T>,compare())可以对列表元素进行排序,并且compare比较方法可以在此自定义,但它所用常量若是在方法外部定义的变量,需添加final修饰符

②用Vector<Vector<T>>实现二维数组需要

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

还好

  1. 关于Eclipse IDE;

挺好用

  1. 关于Git和GitHub;

配置环境太复杂,总是有很多不会处理的bug,git官网教程看不懂,网上教程也良莠不齐

 

  1. 关于CMU和MIT的作业;

作业描述得很清晰,就是英语有点难度,有些地方需要不断地查找才能理解它的意思,这对本人来说还是很有难度的

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

工作量对于一个大二下学期的学生来说其实并不算大,但是对于java零基础的本来来说其实花了更多的时间去学习java的语法而非算法,有一些java的规格说明需要花很大的时间去试错,改bug才能达到目的。Deadline相对合理。

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

软件构造的概念很多,初次接触这门课不知道该怎么学习。随着老师上课的深入,有跟不上的感觉。不过这本来就是该自学的

  1. 疫情期间,只能远程授课,个人在家里完成实验任务,你对该学习方式有什么想法?

挺好,每天睡到8点起来上课,不用走600米去教室,哦耶,课余时间也能干些自己的事,关键是家乡天气好呀