2022年春季学期
计算学部《软件构造》课程
Lab 1实验报告
姓名 | 董宇臻 |
学号 | 120L020711 |
班号 | 2003010 |
电子邮件 | 465992466@qq.com |
手机号码 | 18876532990 |
3.1.2 generateMagicSquare(). 5
3.2.1 Problem 1: Clone and import 8
3.2.2 Problem 3: Turtle graphics and drawSquare. 9
3.2.3 Problem 5: Drawing polygons. 10
3.2.4 Problem 6: Calculating Bearings. 11
3.2.5 Problem 7: Convex Hulls. 11
3.2.6 Problem 8: Personal art 13
本次实验通过求解三个问题,训练基本Java编程技能,能够利用Java OO开发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。另一方面,利用Git作为代码配置管理的工具,学会Git的基本使用方法。
- 基本的Java OO编程
- 基于Eclipse IDE进行Java编程
- 基于JUnit的测试
- 基于Git的代码配置管理
GitHub Lab1仓库的URL地址:
https://github.com/ComputerScienceHIT/HIT-Lab1-120L020711
本人之前已经安装过JDK,此处略过。
之后打开https://www.git-scm.com/,然后搜索网上下载git的教程,找到https://blog.csdn.net/mukes/article/details/115693833?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165138628316782395346541%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165138628316782395346541&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-115693833.142^v9^pc_search_result_cache,157^v4^control&utm_term=git&spm=1018.2226.3001.4187安装git。
接下来是安装eclipse。按照http://web.mit.edu/6.031/www/fa18/getting-started/的教程,在第4步时出现问题。于是再次搜索网上的教程,安装Eclipse IDE for Java Developers。
请仔细对照实验手册,针对四个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但无需把你的源代码全部粘贴过来!)。
为了条理清晰,可根据需要在各节增加三级标题。
n阶幻方是n×n个数(通常是不同的整数)在一个方格中的排列,使得所有行、所有列和两条对角线中的n个数总和为同一常数。在main方法中,应完成以下功能为。
首先,调用五次isLegalMagicSquare()函数,将5个文本中文件名分别作为参数,并判断、生成对应的矩阵,判断是否为幻方然后输出判断结果。同时需要能够处理输入文件的各种特殊情况,若输入错误则终止程序执行(isLegalMagicSquare函数返回false),并在控制台输出错误提示信息。
其次,要将静态方法generateMagicSquare()加入MagicSquare类并且在main方法中测试。
读取文件之后,首先要完成的是检查输入是否合法。
不论文件输入是否规范,只要行列数不相等就一定是非法输入,因此若行列数不等isLegalMagicSquare()就返回false,;若行列数相等,再检验输入的数字是否是正整数。经过这两步检验后,得到的一定是合法输入。
之后将文件存储到静态矩阵square,再分别计算各行、各列和各对角线的和,判断是否符合幻方的定义。
首先把文件存入矩阵,此时可以同时判断各行之和是否符合定义。若各行之和都相等,我们也得到了这个幻方的各列、各对角线之和,声明为sum。
然后再检验各对角线和各列之和是否符合定义,若通过所有检测则返回true。
至此该方法编写完成,运行结果如下。
在main方法中对generateMagicSquare()进行测试。generateMagicSquare()会检验负数和偶数输入,在main方法中需要检验小数输入。main方法如下。
输入5时,测试结果如下。
输入小数3.5时,结果如下。
参数赋值为偶数2和负数-3时,程序无法正常运行。
该方法对于边长为奇数的矩阵适用。首先将初始位置square[0][n/2]赋值为1,之后每次取当前位置的右上角的位置,赋的值每次加1,如果当前行是第一行,则最后一行是下一次要填充的行,如果当前列是最右边的列,则下一次取左边第一列。若下一次要赋值的位置已经有元素了,就取当前位置正下方的位置赋值。如此重复,直到n*n矩阵被填满,就得到了一个幻方。
添加注释后如下图。
如果输入的n为偶数,控制台会产生java.lang.ArrayIndexOutOfBoundsException异常,这是由于数组越界产生的。以输入参数8为例,当i=9时,row=4,col=0,就会产生数组越界。
如果输入的n为负数,控制台会产生java.lang.NegativeArraySizeException异常,这是由于应用程序试图创建大小为负的数组。
接下来要扩展该方法。
- 将产生的magic square写入文件\src\P1\txt\6.txt中。
- 当输入的n不合法时(n为偶数、n为负数等),不要该函数抛出异常并非法退
出,而是提示错误并“优雅的”退出——函数输出false结束。
该任务的目标:clone已有的程序后,利用turtle按照要求画图,主要需要修改及再编程的是TurtleSoup类,其中的一些函数编程时需要结合我们已有的数学几何知识、TurtleSoup类中的提示信息以及测试用的TurtleSoupTest类中的提示信息,最后可以发挥想象力进行自己的创作。
进入GitHub - rainywang/Spring2022_HITCS_SC_Lab1,复制该网址。之后在E盘创建一个文件夹GitCode,进入之后点击右键选择Git Bash Here,输入git clone,再将复制的网址粘贴进去,按下回车,代码获取成功。
或者是通过ssh完成clone。
之后打开Eclipse,选择文件→导入→常规→现有项目到工作空间中,将文件夹P2导入到Eclipse。
-
-
- Problem 3: Turtle graphics and drawSquare
-
该方法要实现的功能是画出指定边长的正方形。阅读Turtle.java,发现四个方法:forward(int units),功能是让海龟沿当前方向前进;turn(double degrees),功能是让海龟顺时针旋转;color(PenColor color),功能是改变海龟当前的画笔颜色;draw(),功能是画图。
让海龟行走一段距离后旋转90度,重复4次就可以得到正方形,代码如下。
测试结果如下。
首先要实现方法calculateRegularPolygonAngle。正多边形每个内角的度数为180-360/边数,于是可以得到如下程序。
然后实现方法calculatePolygonSidesFromAngle。由之前的公式很容易得到结果,需要注意的是double到int的转换。
接下来实现drawRegularPolygon。调用已实现的calculateRegularPolygonAngle来计算出内角大小,再用180减去内角大小得到需要旋转的角度,按照解决Problem 3的方法来编写程序。
首先要实现calculateBearingToPoint:已知起点和终点坐标以及海龟当前朝向,求需要旋转的角度,即当前点到目标点的向量和当前方向向量之间的夹角。首先运用Math类的atan2方法,计算当前点到目标点的向量在坐标系中的角度,这个值位于-π和π之间,所以最后需要分情况讨论。经过数学分析后,编写代码如下:
然后要实现calculateBearings。每次循环通过当前点和计算点,运用calculateBearingToPoint方法计算出要旋转的角度,更新当前的朝向。程序如下。该方法通过Junit测试。
该方法实现了Gift-Wrapping算法,来求出任意一个点集的凸包。首先要取横坐标最小的点,若有多个点则取当中纵坐标最小的,这个点为起始点。然后每次需要旋转的角度最小的点就是下一个目标点。具体思路及代码如下。
所有方法均通过Juint测试。
代码如下。
输出如下。
完成任务后在master文件夹打开Git,输入git add P2/turtle/TurtleSoup.java将P2/turtle/TurtleSoup.java放到暂存区,然后输入git commit -m “Problem 8”,这之后再输入git push https://github.com/ComputerScienceHIT/HIT-Lab1-120L020711,就传递到了github上。
实现Person和FriendshipGraph两个类,模拟社交网络,提供添加节点以及节点之间添加边,通过BFS计算两节点之间最短路的功能。
-
-
- 设计/实现FriendshipGraph类
-
一共要求实现三个方法:addVertex向社交网络中添加新的节点(人),addEdge向社交网络中添加新的边(社交关系),getDistance用来求两个点之间的最短距离。
首先声明一个哈希集合类,用来检测是否用重复的名字加入。
addVertex方法用来添加一个成员,先检查名字是否重复,有则输出错误提示并退出程序,否则将该成员加入集合。
addEdge实现的功能是在a的朋友列表里加上b。
getDistance方法通过广度优先遍历求出两者间的最短距离。若两个参数相等,则返回0。声明一个哈希映射类,来存放人对应的距离。声明一个队列,用于广度优先遍历。
-
-
- 设计/实现Person类
-
定义两个private成员来存放姓名和朋友列表,再定义一个public成员,用于标记该对象在广度优先遍历中是否被访问过。能够从该类获得该对象的姓名和朋友列表,以及向该对象的朋友列表添加新成员。
-
-
- 设计/实现客户端代码main()
-
-
-
- 设计/实现测试用例
-
3.3.4.1testAddVertex
主要测试三方面:在集合中加入成员后,该成员是否存在;在集合中加入多个成员后,集合的大小是否正确;加入重复的成员后能否退出。代码如下。
结果如下,程序正常结束。
当去掉第二个graph.addVertex(a)后,testAddVertex通过测试。
3.3.4.2 testAddEdge
主要测试单向边和双向边,测试在这两种情况下能否从ab的朋友列表找到彼此。通过测试。
3.3.4.3 testGetDistance
主要测试三方面:一个对象到自身的距离是否为0;两个不连通的对象间的距离是否为-1;在复杂的图像能否得出正确结果。代码如下。
首先构造一个简单的有向图,测试前两个方面。
然后构造一个复杂的无向图,测试第三个方面。
3.3.4.4测试结果
编写完成后,所有测试全部通过。
3.3.4.5如果将上述代码的第10行注释掉(意即rachel和ross之间只存在单向的社交关系ross->rachel),请人工判断第14-17行的代码应输出什么结果?让程序执行,看其实际输出结果是否与你的期望一致?
判断:应输出结果为-1 -1 0 -1,实际输出结果与期望一致。
3.3.4.6如果将第3行引号中的“Ross”替换为“Rachel”,你的程序会发生什么?这其实违反了“Each person has a unique name”的约束条件。修改你的FriendshipGraph类和Person类,使该约束能够始终被满足(意即:一旦该条件被违反,提示出错并结束程序运行)。
当所有Person对象全部生成之后,将他们的姓名全部加入到一个集合中,检查集合中元素个数与创建对象数是否相同,若不同则提示出错并结束程序运行。代码及测试结果如下。
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 | 时间段 | 任务 | 实际完成情况 |
2022-05-01 | 20:00-23:00 | 编写问题1的isLegalMagicSquare函数并进行测试 | 按计划完成 |
2022-05-02 | 15:00-17:30 | 编写问题1的 generateMagicSquare函数并进行测试 | 按计划完成 |
2022-05-02 2022-05-03 | 19:30-04:00 | 编写问题2,完成Problem1~5 | 遇到困难,未能按时完成 |
2022-05-03 | 10:00-12:00 | 编写问题2,完成Problem5、6 | 按计划完成 |
2022-05-03 | 14:00-17:30 | 完成问题2 | 按计划完成 |
2022-05-03 2022-05-04 | 21:00-02:00 | 完成问题3 | 按计划完成 |
遇到的困难 | 解决途径 |
对Git的使用不熟悉 | 上网搜索教程自主学习 |
Git无法完成push操作 | 下载github加速器 |
不会使用Junit | 上网搜索教程自主学习 |
我对Java的熟悉程度更高了,也初步学会了如何使用Git和github。在实验过程中,我遇到了许多困难,吃了许多教训,如从github下载文件到本地仓库的流程必须正确。
- Java编程语言是否对你的口味?与你熟悉的其他编程语言相比,Java有何优势和不足?
我认为Java编程语言很符合我的喜好。相比于C语言,Java的使用更加简单,功能更加丰富。不足之处是不如C语言有利于对计算机底层结构的理解。
- 关于Eclipse或IntelliJ IDEA,它们作为IDE的优势和不足;
Eclipse优点:非常适合java语言,开发、编写、查错、编译、帮助等各方面非常方便;有中文版,上手较快;更新速度快;插件功能强大,免费;开源、免费。
缺点:大工程时,吃内存耗CPU,依然会出现很慢、卡顿、奔溃和无响应的情况;插件对eclipse版本要求比较严格,插件更新速度跟不上eclipse更新速度;安装插件过多之后,速度变慢;有些插件安装比较麻烦;对所见即所得的GUI和WEB界面设计,暂没有很好的支持。
- 关于Git和GitHub,是否感受到了它在版本控制方面的价值;
感受到了。
- 关于CMU和MIT的作业,你有何感受;
CMU和MIT的作业强调自主学习,罗列出要执行的步骤,鼓励大家自己动手实操。
- 关于本实验的工作量、难度、deadline;
工作量非常大,难度对于初学者来说较高,对于有基础的同学来说是正常难度;deadline若不是和期末考试冲突,就算得上是合理。
- 关于初接触“软件构造”课程;
这门课程能够很好地锻炼自己的编程能力,有助于掌握一些一个程序员必备的基础技能。