2024年春季学期
计算学部《软件构造》课程
Lab 1实验报告
姓名 张皓涵
学号 2022111897
班号 2237102
电子邮件 [email protected]
手机号码 15134623385
目录
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 编程技能,能够利用 Java OO 开发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。另一方面,利用 Git 作为代码配置管理的工具,学会 Git 的基本使用方法。
⚫ 基本的 Java OO 编程
⚫ 基于 IDE 进行 Java 编程
⚫ 基于 JUnit 的测试
⚫ 基于 Git 的代码配置管理
2实验环境配置
1.安装编写java程序的IDE—— IDEA
2.安装jdk
由于我之前已经配置好了,以下展示cmd中java的jdk版本截图
3.配置环境变量
在Path变量中添加%JAVA_HOME%\bin变量
,
新建一个JAVA_HOME变量,值为jdk路径
4.配置JUnit
5.安装Git
在使用Git的过程中,由于不熟悉Git操作指令,通过老师发的git学习手册以及网络博客进行git学习,,最终成功上传了自己的代码(以下目录仅为测试使用),熟悉了git操作
6.GitHub Lab1 仓库的URL地址
https://github.com/ComputerScienceHIT/HIT-Lab1-15134623385.git
3实验过程
请仔细对照实验手册,针对三个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但无需把你的源代码全部粘贴过来!)。
为了条理清晰,可根据需要在各节增加三级标题。
3.1Magic Squares
本题与Magic Square有关,Magic Square,即幻方,查阅百科后了解到,幻方是一种将数字安排在正方形格子中,使每行、每列和对角线上的数字和都相等的方法。题目1要求编写一个Java程序(MagicSquare)先来检查给定txt文档中所记录点五个矩阵的行/列/对角线值,然后分别判断它们是否是一个幻方。题目2要求对给出的产生幻方的代码(generateMagicSquare)进行改进扩展后加入MagicSquare类中进行测试。在这里简要概述你对该任务的理解。
3.1.1isLegalMagicSquare()
1.函数设计
题目一要求编写一个函数isLegalMagicSquare()判断一个txt文件中保存的矩阵是否为符合幻方要求的矩阵。输入参数为txt文件的文件路径,函数返回一个boolean值,若符合要求返回true,否则返回false。
首先判断幻方的合法性:
根据幻方的定义,首先需要判断幻方必须是行数与列数相等的矩阵,假设幻方为N * N的矩阵,那么幻方的元素值都是自然数集上从1到N * N的一个排列,不能为负数,不能为浮点数,此外,两两元素值也不能相同。最后确定行列和、对角线和之间是否全部相等,若是,则为幻方,函数返回true。
2、实现思路
首先根据函数参数传入的文件路径,使用FileReader读入文件,将字节流转换为字符流,再使用BufferReader将缓冲区的字符流读取文件的内容,并保存在一个br中。
将文件内容读取到后开始对文件内容做处理,使用readLine()!=null方法检测出文本中的行数line,并以此分割出矩阵的每一行,并以保存进一个字符串数组String read1[]中。
同样地,再对矩阵的每一行进行处理,使用split("\t")方法检测出每一行元素之间的分隔标记,并以\t为间隔将其划分为一个个数字字符串,保存在String[] read1[]中,此时可调用length方法计算得出矩阵每行的列数row。
下面进行数据合法性判断,首先判断每行的列数是否等于行数,然后再判断矩阵中数字是否包含小数和负数,来进行判断矩阵是否是幻方,最后使用Integer.valueOf(String ).intValue()方法,得到字符串转换为的数字,循环保存至幻方new_t[][]中。至此,对文件的读入及初始数据的处理完成。
接下来进行判断行列和、对角线和是否全部相等的判断,首先计算出每行的和以及每列的和并存储到sum_line[],sum_row[]以及sumxie[]数组中。
最后判断行列和、对角线和是否全部相等,若是则返回true,否则返回false,并用catch抛出异常数据,至此,isLegalMagicSquare()函数结束。
3.1.2generateMagicSquare()
a.函数设计
在generateMagicSquare()函数中对参数n做判断:若n为偶数,则打印错误信息并返回false;若n为负数,则catch到NegativeArraySizeException错误,同样打印错误信息并返回false。
分析该函数的内容,给定一个参数n作为幻方的行列数,将初始位置置为(0, n / 2), 之后依次对1 ~ n * n赋值给一个位置,1赋值给初始位置,然后计算下一个位置为当前位置的右上位置。对于边界情况:若当前行是第一行,则下一行取最后一行;若当前列是最右边的那列,则下一列取最左边的那列。当i能被n整除时,则将当前位置正下方的第一个位置赋值为i + 1,然后继续循环赋值。当循环n的平方次后,即对整个矩阵赋完了值,且满足每行每列以及两条对角线之和均相同的约束。
b.实现思路
c、写入文件
将产生的magic square写入文件夹\src\P1\txt\6.txt中,使用PrintStream类写入magic数组所存储的矩阵中保存的内容。代码如下所示:
3.2Turtle Graphics
根据本题提示一步一步实现基本功能,逐层深入,通过完成一些比较简单的方法,逐渐添加功能,最后得到一个较为复杂的方法。最终熟悉Turtle Graphics的各种函数接口,自己编写部分函数,并使用Math库的一些函数实现一些计算以画出所需图形。
3.2.1Problem 1: Clone and import
a、获取任务代码
从报告里的链接上获取了源文件所在仓库,在IDEA里建立了相关项目后,首先创建一个本地仓库,然后再通过git clone+ssh密钥建立联系,将源文件下载到本地文件夹,将其复制到IDEA项目的src中,IDEA刷新后,即可被使用。
b、使用Git管理本地开发
先使用git init创建本地仓库,然后和远程仓库连接,git pull拉取代码
实现一个功能后用git add .上传项目文件,然后git commit_m、git push提交到远程仓库上。
3.2.2Problem 3: Turtle graphics and drawSquare
题目要求使用Turtle类中给出的forward()方法和turn()方法,参数是海龟对象turtle和边长sideLength,最后实现出能够画出边长为指定数值的正方形。
实现思路:
循环执行4次,每次forward前行sideLength的距离,然后画笔方向旋转90度,继续下一次执行。即可得到所要求的正方形。实现结果如下(sideLength = 100):
函数代码如下:
3.2.3Problem 5: Drawing polygons
题目要求实现能够画出正多边形的函数drawRegularPolygon()。首先需要实现一个辅助函数calculateRegularPolygonAngle()用于计算正多边形的每个内角度数。由数学知识可知,该函数实现如下:
通过TurtleSoupTest中的Junit测试后再调用calculateRegularPolygonAngle()得出所求正多边形的内角度数,类比画正方形的函数,由数学公式可知,代码实现如下:
画出一个边长为100的正六边形,效果如下:
3.2.4Problem 6: Calculating Bearings
a.calculateBearingToPoint方法:
给定当前朝向(以正北方向为0°,顺时针方向),坐标和目的地,计算旋转角度的大小(始终向顺时针旋转,旋转角度在[ 0 , 360 ° ) [0,360\degree)[0,360°)中)对于每个target坐标,先计算它相对于当前位置的偏转角θ(代码中的targetBearing),可以通过Math库中的反三角函数实现(弧度制要转化成角度制);此外,由于反三角函数返回[ − π / 2 , π / 2 ] 中的值,无法区分30°和150 ° , 需要判断一下target的相对位置(在current的上方还是下方,注意坐标轴的情况),代码实现如下:
b.calculateBearings方法:
给定两个List xCoords和yCoords,分别含有一系列横坐标和纵坐标,且个数相同(记为n nn);设最初turtle的朝向为正北并在(xCoords[0], yCoords[0])处,计算n − 1 n-1n−1次转向的角度。当n = = 0 n0n0,返回空列表。calculateBearings用calculateBearingToPoint很好实现。记录当前位置和朝向,不断调用calculateBearings即可。*List是抽象类,需要返回其子类ArrayList。
运行并通过了Junit测试
3.2.5Problem 7: Convex Hulls
根据题目提示,运用Gift wrapping algorithm算法,每次都选择转向角最小且点间距离最长的点加入集合中,计算转向角度可使用上题的calculateBearingToPoint函数。其中相同转向角点之间的取舍,可以在循环中使用标记变量Dist_target记录其与当前目标点的距离,如果之后出现了新的目标点,就用Dist_target和计算得到的当前点的距离Dist_temp来比较,取更大者为新的Dist_target。
3.2.6Problem 8: Personal art
实现思路:在画正多边形的基础上,每次使得步长增加,并且角度比画正多边形需要的角度略多一点,每次拐弯变换一次颜色,达到多个多边形重叠绚丽的效果。
3.2.7Submitting
A.初始化仓库
git init
A.添加仓库url
git remote add origin https://github.com/15134623385/HIT-Lab1-2022111897
B.上传所要上传的文件
git add.
C.提交并添加备注
git commit -m “ XXX”
D.上传文件
git push -u origin master
3.3Social Network
题目要求设计实现一张社交关系网络图,并编写一个计算人机关系“距离”的函数。网络图基于两个类,分别是FriendshipGraph类和Person类。设计/实现FriendshipGraph类
3.3.1设计/实现Person类
保存对象名字的字符串
3.3.2设计/实现客户端代码main()
addVertex方法的实现:采用HashSet以及put方法存储无重复的顶点
addEdge方法的实现:
getDistance方法:进行BFS搜索即可,使用HashSet以及HashMap进行存储,如果到达目标点,返回最短路径长度
1.采用题目提供的main代码,不修改原代码,运行结果如下:
2.注释掉graph.addEdge(rachel,ross)
原因是:
从rachel到ross的边不存在了,所以rachel,和ross距离-1,其他点也无法达到。只有getDistance(rachel, rachel)返回0。
3.输入重复名字
结果为:
原因是在前面代码中设置了查找到重复名字就退出的检查
3.3.3设计/实现测试用例
1.单向的有向图
图为为a->b->c->d,由运行结果可知,a、b之间距离为1,b、a之间没有路径,结果为-1,a、d之间距离为3,测试用例通过
2.带环和断点的有向图
图为:
运行结果如下图所示,a、f之间距离为3,a、d之间距离为2,a、f之间没有路径,结果为-1,同样地,a、c结果也为-1,测试用例通过
3.双向的无向图
图为:
运行结果如下,a、d之间距离为2,d、a之间距离为2,c、b之间距离为2,b、c之间距离为2,a、e之间没有路径,结果为-1,测试用例成功:
4实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
日期 时间段 任务 实际完成情况
2024-03-23 14:30-17:30 编写问题1的isLegalMagicSquare函数并进行测试 延时1小时完成
2024-03-24 14:30-17:20 编写问题2的大部分问题,凸包算法未完成 遇到困难,未完成,凸包算法为未完成
2024-03-26 18:30-20:10 编写了问题2的凸包算法 按计划完成
2024-03-28 18:30-20:20 编写了问题三的Person类和addVertex以及addEdge,并构思了getDistance 按计划完成
2024-03-30 14:30-17:40 编写了问题三的getDisatance 按计划完成
2024-03-31 14:30-17:50 编写测试用例后,发现程序有问题,进行修改bug 延时完成
2024-4-3 14:30-17:30 完成实验报告 按计划完成
5实验过程中遇到的困难与解决途径
遇到的困难 解决途径
对于Java的语法掌握的不够熟练,时常想好了做什么,但是找不到合适的对象、方法去实现自己的想法。
查询csdn和Java官方文档,不断积累经验和思路方法,来提升编程能力
对于IDEA的使用不太熟练,对于其文件夹的设置不熟练
上网查询IDEA使用方法,在编程过程中不断磨合,使得更加熟练
对于Junit测试的使用,以及测试用例的编写不太熟练
上网查询Junit的用法,设计更多的测试用例,最终熟能生巧
Java的编程环境,jdk版本配置不太熟练
上网查询环境变量的配置,以及jdk下载和版本选择
6实验过程中收获的经验、教训、感想
6.1实验过程中收获的经验和教训(必答)
收获的经验:在实验的过程中,由于之前接触Java并不多,学习时通过和C语言比较,感受到了Java面对对象编程的特点,编程序的时候,一定要清晰地想好解决问题的思路,再去编程,这样能节省不少时间,也不会出现前功尽弃的情况,事先分析,思路清晰可以使编程逻辑更加简约灵活,提升编程的效率;此外,程序的健壮性不容忽视,通过编程发现,本以为完美的程序实际上还有很多种情况没有考虑,所以,我们应该采取考虑所有可能的情况,并通过Junit单元测试进行测试,这样测试成功出来的程序往往具备更好的健壮性,让程序更加完美、逻辑缜密;
收到的教训:编程序不能拖延,今日事今日毕,否则拖延之后使得编程不连贯,降低了编程效率,此外,我对与Java的类库等语法的掌握非常不熟练,在实现的过程中因为语法而受到了不小的阻力,所以希望以后抽出时间多学习Java语法语义,尽可能提升编程能力,为以后就业做准备。
6.2针对以下方面的感受(必答)
(1)Java编程语言是否对你的口味?与你熟悉的其他编程语言相比,Java有何优势和不足?
是,Java编程语言对我的口味;与我熟悉的C语言相比,我认为Java语言的
优势有:面向对象编程,有很多数据结构可以直接使用,提供的库函数功能十分强大,更加简洁易上手;
不足有:不贴合程序的底层逻辑,运行速度较慢,不能更直观地了解一些数据结构的具体实现。
(2)关于Eclipse或IntelliJ IDEA,它们作为IDE的优势和不足;
我使用的是IDEA,它作为IDE的优势在于插件丰富,界面美观简洁,IDEA的功能比较完善,比如refactor、单元测试等方法是非常便捷的,并且也会提示你是否用Git管理等等;
缺点是,IDEA 很多强大的功能都是基于其缓存与索引,当打开一个新项目的时候,IDEA 会自动建立索引。这个有时候对大型项目特别不友好,可能会出现卡顿现象。特别对于机械硬盘用户,这种现象会更加明显。
(3)关于Git和GitHub,是否感受到了它在版本控制方面的价值;
是的,感受到了Git和GitHub在版本控制方面的价值,可以版本回退,不用担心修改后找不到之前较好的那一版,使得我们程序员的工作更加快捷方便。
(4)关于CMU和MIT的作业,你有何感受;
向世界一流计算机强校学习势在必行,并且使得我们完成其任务后更有成就感,感到编程能力进一步提升。
(5)关于本实验的工作量、难度、deadline;
本实验的工作量较大,对我来说难度不小,是一个挑战,deadline感谢老师延期,让我缓解了一些课程压力。
(6)关于初接触“软件构造”课程;
首先,对于Java编程非常不熟练,需要大量查阅资料,其次,英语阅读略有困难,总之,这门课对我来说难度不小,是一次挑战,也是我提升编程能力的一次机遇,希望以后好好努力深入理解这门课程。