Software Construction Lab1

在这里插入图片描述

Software Construction Lab1

1 实验目标概述

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

2 实验环境配置

依照实验要求,依次安装了eclipse与git,为eclipse配置了Java8环境,学会使用GitHub创建原程仓库并将其与本地git仓库相关联。
在这里给出你的GitHub Lab1仓库的URL地址:
https://github.com/ComputerScienceHIT/xxxxxxx

3 实验过程

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

3.1 Magic Squares

幻方实验主要有两个函数,一个是isLegalMagicSquare判断已有的文件中存储的矩阵是否是幻方,另一个generateMagicSquare用来生成一个奇数阶的幻方。

3.1.1 isLegalMagicSquare()
  1. 从文件中读取数字矩阵,获取文件输入流后,可以按行读取数据,

  2. 检测每一行中是否有“.”“-”用以检测浮点数

  3. 使用split方法后,判断行列数是否相等以及每一行数据量是否相等
    在这里插入图片描述

  4. 保证数据为方阵后,按幻方的规则进行计算,左边计算行列,右面计算对角线

在这里插入图片描述
在这里插入图片描述

结果如下
在这里插入图片描述

3.1.2 generateMagicSquare()

将所给函数加入MagicSquare 类后,研究其行为是如何产生幻方的,得流程图如下
在这里插入图片描述

1、 java.lang.ArrayIndexOutOfBoundsException
数组越界造成的异常,使用了不合法的索引访问数组,导致数组越界。在使用偶数n的情况下,循环运行到第(n/2 * n)次的时候,都会执行row++,然而此时已经在整个数组的第(n-1)列,所以下一次访问就出现了越界。
2、java.lang.NegativeArraySizeException
程序尝试建立大小为负的数组时抛出的异常。原因是n取负数时,建立二维数组的时候会将行数和列数取成负数,导致该异常抛出。

3.2 Turtle Graphics

提供了一个现成的图像绘制工具,实验目的是通过调用现成的一系列功能来实现绘图/计算方法。

3.2.1 Problem 1: Clone and import

从GitHub:
https://github.com/rainywang/Spring2022_HITCS_SC_Lab1/tree/master/P1
获取该任务的代码、在本地使用git bash创建git仓库,git clone导入到本地、使用git管理本地开发。

3.2.2 Problem 3: Turtle graphics and drawSquare

阅读turtle.java得知接口,且这些方法在其它类中已经实现了,所以在drawSquare中直接调用,尝试后发现turtle转向只能向右转,所以每次90度之后向前走参数长度的距离即可完成任务。

3.2.3 Problem 5: Drawing polygons

先实现calculateRegularPolygonAngle方法,(180.0 * (sides - 2) / sides),以用边数得到正多边形内角度数,顺便实现calculatePolygonSidesFromAngle,只要让turtle每次向前参数长前,旋转(180度-内角度数)即可完成任务。

3.2.4 Problem 6: Calculating Bearings

使用Math.atan()方法输入Δx/Δy得到弧度制角,转化为角度制角后可以进行分象限讨论(依照向量(Δx,Δy)),可以得到正上方向与向量的夹角(0360),然后与正上方向与当前方向的夹角作差,增加360度再模上360可以保证结果范围在0360度之间。

3.2.5 Problem 7: Convex Hulls

此问题要求求解凸包,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点。这里运用Graham扫描法,先确定最下面的点P0,然后按照剩余点与P0形成有向连线与x正轴所成极角来对点集进行排列,入栈T使栈顶极角最小,极角最小的点P1出栈。然后P0,P1入栈S依照极角从大到小依次进行如下操作:
1.按序列(T弹出)取出P后,
2.考察S栈顶Pi+1与栈顶的上个元素Pi,若向量PiP极角小于PiPi+1极角(此处极角取基准向量x正半轴逆时针方向,且将其数值限定在连续单调的0~2pi之间)就将Pi+1弹出S并舍弃,回到步骤2开始使用新栈顶Pi与Pi-1,否则,Pi+1维持栈中,P压入栈S,再回到2开始。这样一直到栈T空。
最后得到的S中的元素导入点集,就是凸包
考察Junit测试样例发现,要求的凸包还要求是最小点集,所以上述步骤2中应是小于等于。简化后流程为
1.按序列(T弹出)取出P后,
2.考察S栈顶Pi+1与栈顶的上个元素Pi,若向量PiP极角大于PiPi+1,就使 Pi+1留在栈中,P压入栈S,再回到步骤1开始。否则就将Pi+1弹出S并舍弃,回到步骤2。这样直到栈T空。
最后可得最小凸包。
实施过程:

  1. 使用Math.atan2()方法计算极角,但其返回值在(-pi,pi]为保证极角比较,只要计算所得小于0,全加上2pi,这样以后保持了[0,2pi)的单调性。
  2. 访问栈顶的上一个元素至少要提前弹出Pi+1,可据此调整代码
    核心算法实现如下
    在这里插入图片描述
3.2.6 Problem 8: Personal art

根据勾股数5,12,13,以原点为中心逆时针作三角形,大量循环形成炫彩呼啦圈。
在这里插入图片描述
在这里插入图片描述

3.2.7 Submitting

使用如下命令:
git add
git commit -m “P2 update ,optimize it”
git push master
YAY!

3.3Social Network

一个简单的图算法,广度优先搜索最好,不过此处要求面向对象编程,给出了图与人两个对象。尝试在人,图中用实际意义组织数据结构。
可以在FriendshipGraph类中使用List,在Person类中使用friend集,组合起来形成了类似邻接表一样的数据结构,可以此为基础进行BFS,达到getDistance的目的

3.3.1 设计/实现FriendshipGraph类

UML如下:
在这里插入图片描述

如图,考虑图应该实现:

  1. 记录目前图中总人数:numberOfPeople
  2. 方便判断新得到的人是否已经在图中或不在图中:借助nameSet.contain()
  3. 组织人口数据表,方便进行查找增改操作:personList
  4. 加入人,着重判重:addVerTex()
  5. 加入“认识”关系:addEdge()
  6. 获取社交关系距离:getDistance()
  7. 测试主方法:main
3.3.2 设计/实现Person类

UML如下
在这里插入图片描述

  1. 人的姓名:常量Name
  2. 距离存储变量,用于计算时临时保存某人到其距离:distance
  3. 防止距离查找时重复访问:visited
  4. 保存实例所“认识”的人的集合:friend
  5. 保存在List中的索引值:index
  6. 安全获取姓名:getName()
    3~5都是在social network中存Person节点时必须用到的
3.3.3 设计/实现客户端代码main()

main()方法使用实验指导pdf所给出的程序,建立social network并运行,所得结果与预期相符:
在这里插入图片描述

手动按要求修改:

  1. 将rachel→ross的边删掉,结果符合预期
    在这里插入图片描述

  2. 改ross为rachel得,程序报错正常退出。
    在这里插入图片描述

3.3.4 设计/实现测试用例

设计额外一张大图对程序进行测试:
在这里插入图片描述

下面是利用Junit的测试代码
在这里插入图片描述

可以看到,不在同一弱连通分量,非是强连通,正常单向可达均测试成功。
4 实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
日期 时间段 任务 实际完成情况
2022-05-02 15:30-17:30 学习廖雪峰的git教程,基本掌握 按计划完成
2022-05-02 19:30-21:30 完成P1中的第一小问 延期1小时完成
2022-05-03 14:30-15:30 学习异常,完成P1 按计划完成
2022-05-03 15:30-18:30 完成P2到Problem6 顺利完成
2022-05-03 20:00-23:00 完成凸包的学习,编程 超时,延时3小时完成
2022-05-04 14:30-16:30 完成P3两个类的编写 按计划完成
2022-05-04 19:30-20:30 完成P3test的编写 按计划完成
2022-05-04 20:30-21:30 代码加注释,去冗余 超市
2022-05-04 21:30-23:30 完成报告等 超时,延时3小时完成
5 实验过程中遇到的困难与解决途径
遇到的困难 解决途径
幻方的检查工作中出现的各种问题

  1. 文件流读取不通过与异常,文件写入时将后续控制台输出写入文本
  2. 幻方bug:无法读入最后一列,直接跳过 1. 学习IO与文件流,使用现成的稳妥方案,保存控制台输出流,在文件写入后重新setOut改回来
  3. 查找bug,投入大量时间,论证split后是否有回车符的影响,最后发现数组索引有误
    凸包算法相关问题
    未完全采用graham法,自己的理解出现Bug,程序始终不通过第四个样例
    1. 重新理解凸包算法,未按照极角大小序列输入循环是算法的一个问题
  4. 发现极角比较中atan返回值与预期的单调性不一致,调整数据以维持单调区间
    FriendshipGraphTest问题
    重新构造大图使用Junit测试,调试未通过的
    回程序插入对friend集的遍历输出,发现P10莫名缺失,调整原方法无效,最后发现问题出在未向图中添加P10节点,测试通过

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

6.1 实验过程中收获的经验和教训(必答)

经验:
  1. 收获了对面向对象编程的初步实践,感觉上手较为容易
  2. 掌握了git与github的大量基础知识,熟练运用
教训
  1. 对Java语言基本特性的充分了解是必要的(引用,接口),即使是要在Java中做C中很方便的事情。
  2. 编程前对编程算法细节有足够的思考,演草与论证是必要的,
  3. Java语言需要大量的编程实践,有好多现成的数据结构与方法可以简化实现的步骤
  4. 练习少了低级错误就多了,大量消耗时间

6.2 针对以下方面的感受(必答)

(1) Java编程语言是否对你的口味?与你熟悉的其他编程语言相比,Java有何优势和不足?
Java语言的基础类型与方法十分方便,对内存的自动管理、无指针等等避免了许多问题,并且基础语法相对C比较简单,装载别人的jar很方便。
但同时感觉有时一些特定的数据结构由于无可用方法,没有使用指针的C语言要灵活
(2) 关于Eclipse或IntelliJ IDEA,它们作为IDE的优势和不足;
Eclipse 用起来还是可以的,但是很多插件下载过慢,也许没有IDEA方便。
(3) 关于Git和GitHub,是否感受到了它在版本控制方面的价值;
基本操作已经熟练,控制版本价值上,实验毕竟不算大型多人合作项目,还是体会不够
(4) 关于CMU和MIT的作业,你有何感受;
就这两个问题而言,MIT的实验有趣而贴近于真正的多人合作,在别人的成果上继续实践,有更强的现实意义,而且画图任务既有趣又富有开放性,而CMU要抽象一些,要求更加像甲方那样子。
(5) 关于本实验的工作量、难度、deadline;
工作量:还挺大的,难度一般,deadline如果不是与形式语言与自动机考试撞了我肯定不会多说什么,唉。
(6) 关于初接触“软件构造”课程;
课程教授的东西还是很抽象的,必须在实践中体会。这是一门值得大量时间且必须投入大量时间才能深刻理解的课程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值