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
- 实验目标概述
通过求解三个问题,训练基本 Java 编程技能,能够利用 Java OO 开发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够
为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。
另一方面,利用 Git 作为代码配置管理的工具,学会 Git 的基本使用方法。
- Java OO 编程
- intellij idea进行 Java 编程
- JUnit 的测试
- Git 的代码配置管理
- 实验环境配置
Windows64;
intellij idea;
Jdk 10;
git
一、实验过程
3.Magic Squares
编写一个程序,对输入的方阵文件测试其是否满足幻方的要求。
3.1.1 isLegalMagicSquare()
首先读取文件,用fileReader函数读取文件,用try catch满足文件不存在时则报错直接返回;
第二步,用bufferReader函数保存文件,便于后续读读取到数组中。
接下来设置arraylist,首先用string类型一维数组保存每一行的输入,接下来用分片split函数,将每一行的字符用\t区分开。
然后用Integer.valueof判断每一小块string是否满足输入的是正整数,用条件语句区分输入为小数或者负数的情况,若输入不为数字(空格符或其他),则catch报错输入的不是一个方阵;若输入的是小数或者负数,则在循环结束后返回false。
3.1.2generateMagicSquare()
流程图如下:
首先对于出现java.lang.ArrayIndexOutOfBoundsException的情况,是指数组越界导致的报错,在判断语句if (i % n == 0)中,出现当i是n的倍数时,row=n-1的情况,例如当n=4,i=8时,row=3,此时row++会导致row=4,即数组越界。
对于出现java.lang.NegativeArraySizeExcept的情况,是初始化二维数组时,n为负数的原因导致报错。
接下来根据已有的代码,首先判断输入的n是否符合标准,符合标准的情况下,首先用新创建一个file类型文件,设置为.txt文件,并添加指定路径。接下来file.createNewFile()生产文件。用Filewriter方法和Bufferwritter方法向文件中输入方阵。
3.2 Turtle Graphics
通过给定的源代码,自己写turtle的方法,使得完成画正方形,画多边形,计算转角,凸包算法等操作。
3.2.1 Problem 1: Clone and import
由于无法连接 MIT 的 didit 服务器,我按照要求从https://github.com/rainywang/Spring2022_HITCS_SC_Lab1/tree/master/P2网站获取代码,将zip文件下载到本地,并用idea打开。
3.2.2 Problem 3: Turtle graphics and drawSquare
可以看到在Turtle.java已经定义了画图需要使用的接口,画图时直接调用就好。
根据Turtle类,forward(int units) 方法的功能是向前平移units个单位;turn(double degrees) 方法是顺时针转90°。
所以第一步画正方形,就是先向前平移sideLength个单位,然后转90°,重复四遍。
3.2.3 Problem 5: Drawing polygons
由多边形定义,可以推导出正n边形边数公式为:sides=360/(180-angle),正sides边形内角公式:(边数-2)*180°/sides,调用写好的calculatePolygonSidesFromAngle函数,可以求出正多边形的内角度数,然后用同样方法画正多边形,循环的次数改为sides。
3.2.4 Problem 6: Calculating Bearings
首先对于函数calculateBearingToPoint,计算处从一个点到了一个点相对角度,并与当前方向做差得到需要偏转的角度。
然后此函数调用calculateBearingToPoint,每次得到的方向作为下一个偏转的当前方向,进行迭代即可。
3.2.5Problem 7: Convex Hulls
这里我才用了边缘平滑法,首先遍历每个点得到y值最小点中x值最小的点作为起始点,然后套一个二重循环,内层循环设置一个当前起点,最开始初始化为起始点,然后遍历其余点,找出从当前起点开始,以从y轴正方向为0角度开始的偏转最小角度的点,若多个角度相同的最小点则找与当前起点距离远的那个点。
图3.2.5.1 内层循环找最小转角点
然后退出内层循环,将该点作为下一个当前起点,并加入凸包集合。此时遍历所有点,得到最终的凸包集合。
3.2.6 Problem 8: Personal art
这里我首先设置颜色为红色,通过多次角度调整与尝试,得到了一个心形,再修改方向到初始方向,forward函数向上走一步,然后循环化了多层使得心形更立体,最终得到一个3D的心形图案。
3.2.7 Submitting
如何通过Git提交当前版本到GitHub上你的Lab1仓库。
3.3 Social Network
该任务要求设计一张社交网络图,基于连接人与人,并且能计算任意两人之间的联系情况。网络图基于两个类,分别是FriendshipGraph类和Person类。
3.3.1 设计/实现FriendshipGraph类
这里首先设置最大值max=100,用来表示邻接矩阵中不相邻的值,以及数组最大值。
然后设置Person类的数组,保存每个人的信息。
设置邻接矩阵edge。
设置Person-Integer键值对,用以方便人在数组中的表示。
设置visited访问数组,在getdistance方法中使用。
接下来设置简单的添加节点和添加边的函数。
最后getdistance函数,这里采用更适合邻接矩阵的求最短路径算法迪杰斯特拉算法,首先初始化距离数组,然后在此基础上遍历其余顶点,找到一个相邻点,再遍历未访问的点,若未确定是否是最短路径上的点,则若新的距离小于旧的距离则覆盖原来的距离,得到最后的最短路径。
3.3.2 设计/实现Person类
包含字符串型的名字,以及Person.Name()方法。
3.3.3 设计/实现客户端代码main()
首先初始化邻接矩阵,然后赋值作业要求里的代码即可。
3.3.4 设计/实现测试用例
首先新建一个package,在底下建一个class文件。然后右键package,点击打开模块设置,将package设置为测试源文件夹,然后在class文件里构建方法,每个测试方法前添加一个@Test标记,接下来idea会提示安装junit到依赖中,按步骤安装后导入org.junit.Assert.*和org.junit.Test包。
然后对应每个方法写测试类,用assertequals和asserttrue函数判断是否符合预期
4. 实验进度记录
日期 | 时间段 | 任务 | 实际完成情况 |
2022-05-01 | 15:30-17:30 | 编写问题1的isLegalMagicSquare函数并进行测试 | 按计划完成 |
2022-05-01 | 19:30-20:30 | 分析问题1的generateMagicSquare函数报错问题 | 按计划完成 |
2022-05-02 | 8:00-11:40 | 编写问题2的drawSquare,Drawing polygons,calculateBearing, calculateBearingToPoint函数 | 延时1小时完成 |
2022-05-02 | 14:00-17:00 | 编写问题2的convexHull函数 | 按计划完成 |
5. 实验过程中遇到的困难与解决途径
遇到的困难 | 解决途径 |
问题1的第二个函数难以做到静态检测 | 使用debug在函数体中调试,观测数值发现问题所在。 |
问题2中calculateBearingToPoint函数理解有误,导致函数无法通过检测 | 与同学讨论后得出正确理解,重写代码。 |
问题2中convexHull函数较为复杂,出现同一直线上的点都被包括进去的bug | 添加距离变量,同一角度下只取距离较大的点加入凸包集合。 |
问题3中数据结构设置困难 | 通过查阅资料,学会使用hashmap键值对以及其方法。 |
问题3中不了解测试用例设计 | 查阅资料,学会设置模块,并依据问题2的测试集来自己编写测试集。 |
问题3中getdistance函数未能用深度优先搜索实现 | 依据现有数据结构,不使用bfs而是选择更适合的迪杰斯特拉算法实现。 |
6. 实验过程中收获的经验、教训、感想
6.1 实验过程中收获的经验和教训(必答)
实操了用java编程,学会了建立github仓库,环境配置以及部分git代码的用法。同时遇到不会的要多查阅资料,提高自学能力。
6.2 针对以下方面的感受(必答)
1. Java编程语言是否对你的口味?与你熟悉的其他编程语言相比,Java有何优势和不足?
对口,java语言有许多包装好的类方法以及数据结构类型,使用起来较c语言更方便。
2. 关于Eclipse或IntelliJ IDEA,它们作为IDE的优势和不足;
个人更喜欢IntelliJ IDEA,由于之前使用过pycharm,这个界面风格对我来说更为舒适。
3. 关于Git和GitHub,是否感受到了它在版本控制方面的价值;
感受到了。
4. 关于CMU和MIT的作业,你有何感受;
感觉很有意思,也都是很能提高能力的习题。
5. 关于本实验的工作量、难度、deadline;
工作总量较小,难度较低,适合入门java和git使用。Deadline和考试冲突,所以在时间安排上略为尴尬。
6. 关于初接触“软件构造”课程;
接触了很多新的东西,包括新的语言,新的编译器,新的平台,都是十分不错的体验,能开拓视野,提高能力。