HIT-2022年春季学期《软件构造》Lab 1实验心得

1.实验目标概述

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

问题1:写一个判断幻方矩阵的程序,要求输入格式为使用\t隔开的正整数,程序需要可以判断该矩阵是否是幻方,并且抛出相应的错误提示,并修改一个生成幻方矩阵的程序

问题2:填补一个用以绘图的工具,并在此基础上绘制一个属于自己的图像,是函数均通过检测

问题3:写一个可以表达好友关系的程序,需要能够增加新的Person,增加关系,并计算两个人之间的距离,为这些函数书写测试程序。

2.实验环境配置

Eclipse IDE for java Developers-2022-03

下载链接: Eclipse Downloads | The Eclipse FoundationThe Eclipse Foundation - home to a global community, the Eclipse IDE, Jakarta EE and over 415 open source projects, including runtimes, tools and frameworks.https://www.eclipse.org/downloads/Java SE 11.0.14

下载链接:Javahttps://developer.oracle.com/java/GitHub Desktop

下载链接 : GitHub Desktop | Simple collaboration from your desktopSimple collaboration from your desktophttps://desktop.github.com/

        由于曾经兴趣使然,和不同的同学参与过Minecraft的mod开发,java环境和编译器的配置与我而言并不陌生,但后续对本实验要求有所修正,要求使用java11,于是我重新下载安装了java11和Eclipse,并修改了环境变量。

       对于git,操作手册写的很详细,操作也很简单方便,但由于之前的开发过程使用过GitHub Desktop,继续使用它对于我更得心应手,所以选择使用GitHub Desktop代替g

3.实验过程

3.1 Magic Squares

        首先此题的要求是测试一个矩阵是否幻方,修改幻方代码并测试,对于MagicSquare,小学时和高级程序语言设计的SSE网站上均有所提及,此题的难度在于如何充分利用java的库函数来为程序提供方便。

        第一步是判断文档的测试用例是否是幻方矩阵,这里由于判断条件苛刻,我们大可以采取多次打开的手段来仔细判断。

        第一次打开文件我们只需要判断输入格式是否合规即可,这一步我们利用str.split(“\t”)分割数据,利用matches(“[0-9]+”)判断,在这一步,由空格分隔的数和小数都将被筛选出并且报错,顺便可以记录矩阵有几行,方便下一步判断。

        第二次打开的时候已经确定输入合规,可以以此判断每行的长度是否都和行数相同,如果有一行不同,则打印错误信息。

        第三次打开就可以放心的将它输入进一个数组中,并进行简单的数据加和,判断是否满足幻方矩阵的性质。

这里可以明显看出java语言的优势,对于C语言来说,判断输入是否用\t来分割是很复杂的,但java中就可以简单的使用str.split(“\t”);来直接读取,用a.length来得到长度。

        程序的生成过程大概是这样,幻想一个n*n的表格,将1填写到第一行最中央,依次向右上方填写下一个数,上方出界则放到这一列最下方,右侧出界放到最左侧,重复和无处可填则填写在自己下方,直到填完为止。

        在大一刷SSE的时候,有很多离谱的测试用例,非常令人气愤的是居然还有一个6*6的矩阵,这让我的代码没有一次通过,但实际上这样的矩阵是不合规的,只有奇数边长才满足条件

小学的时候为辅助记忆,有这样一个口诀:

一居首行正中央,依次斜填右上方

上出格时向下放,右出格时向左放

位置重复填下方,无处可写一个样

按照这样的口诀就可以轻松编写这样的函数了。

​​​​​​​3.2 Turtle Graphics

        这个实验是MIT的经典实验,通过自己完成几个函数来层层递进,最后实现求闭包的算法,并绘制自己的图案。

        这里由于我使用了GitHub Desktop,只要选择正确的仓库,点击clone就可以把任务代码pull到本地库中。

 这里克隆了一个测试用空的库作为示例。

想要画出一个正方形,只需要前进,左转90度,重复四次即可。

        这步分为两个函数,第一步是计算正多边形内角,实际上只是计算各个角都相等的多边形内角,然后,模仿画出正方形的步骤,画出正多边形。

        首先是calculateBearingToPoint,它可以计算原点到一个点的向量和这个点到另外一个点的向量的夹角。然后补全calculateBearings,多次调用上一个函数来实现它的功能

 这里又是相比于C语言,java的优点所在,List<Integer>使用和调用非常方便。

        这是计算凸包的方法,对于平面上的一些点,总可以找到这样一些点,由他们依次相连构成的凸多边形可以让其它所有点均在多边形内,这样的点集合和凸多边形是唯一的。

        在数学上,这样的方法很简单,只要取出平面上一条让所有点都在它一侧的直线,任取一点为轴,顺时针旋转,若碰到另外一个点,则以这个点为新的转轴,当再次碰到同一个点,则结束旋转,被碰到过的所有点即为凸包集合,于是可以用计算机模拟这个思路。

        方法也很简单,只要对于一个点,找到其它所有点中和它的连线与之前找到它的连线夹角最大即可,虽然计算机的计算不是连续的,即无法像数学上一样用一条线旋转,得到”优美的”证明,但也可以选取夹角最大的点来模拟这一思路,多点共线的情况下只需要选取最远的点即可。

        这里就可以写一些实验报告上不方便提及的事情,比如借助旋转的算法,对于每一个点,我们可以求出以他为轴各个其它点的偏转角,并排序,当一个点被旋转得到,那就找到这个点旋转角顺序表中的下一个点,遗憾的是,测试用例中包含三点共线的情况(令人不悦),这样的情况对于建表有一些影响,但这样的方法毫无疑问在理解上是更优美的,在旋转过程中染色,连接,当然,这个思路来源于IMO2011年第一天的第二题,感兴趣的同学大可以去找来看看,体会连续过程中的不变量在解题过程中的作用。

        这里可以随意作画,我采用画一次转九十度,再画一次,转九十度,长度增加的方式作画,得到了一个有趣的图案。

 

  • ​​​​​​​​​​​​​​Submitting

这里直接在GitHub Desktop 中commit to master,然后上传即可

如果用git,则使用

git add *->git commit -m “”->git push提交

当然了,大人,时代变了,现在win下的git方便程度实在是远不及Desk了,谁还想用git这么繁琐的东西呢?

​​​​​​​3.3 Social Network

利用java的图结构绘制一张人际关系网络,并且对其进行测试。

        实现FriendshipGraph类

        查阅实验手册,可以发现需要addVertex函数,addEdge函数,getDistance函数。

 

        addVertex函数首先需要判断姓名是否重复,然后创建一个新的对象,加入图表 ,addEdge函数只需要调用Person类的addFriend即可。getDistance函数是利用广度优先搜索,找到一个最短的路径,早在数据结构课上用C语言就可以轻松实现,利用java则更为简单,调用队列和哈希表即可,当然直接调用这些功能对于绝大多数同学来说太过于陌生了,大家都并没有学过一门OOP语言,一年前小学期开设的计算机专业的相关课程都被很快抢走,而我也只是抢到了一门matlab的课,对于大多数同学,学习java的过程很困难。

        实现Person类

Person类的功能不复杂,只要有姓名和好友列表就可以。​​​​​​​

        实现测试用例

测试分为三个部分,分别测试三个函数,

        首先是addVertex,判断新加入的人是否是最后一个即可。对于addEdge,和上面的方式一样,测试新加入的边是否是好友列表的最后一个。对于getDistance,生成一个六个人的关系网进行测试,由于代码有扩展有向图功能,这里对于有向图直接进行测试。

Java编程语言是否对你的口味?与你熟悉的其他编程语言相比,Java有何优势和不足?

整体上Java很对我的口味

        优势:相比于C语言,它有更丰富的库文件,可以方便我面向对象进行编程且功能更加齐全,尤其是try和catch,可以很轻松的帮我解决程序出错的问题

        不足:java在编译过程中的依赖等文件很多很复杂,体量很大,不易在短时间里学会,如果不了解这些,java的优势就不能体现出来。

关于Eclipse或IntelliJ IDEA,它们作为IDE的优势和不足:

        关于Eclipse,它的界面比较朴素简单,功能齐全,优势上就是它较为容易入手,不足上,则是它的颜色显示以及对于空格和的补齐能力不够强大,与VS2021相比更是逊色很多

关于Git和GitHub,是否感受到了它在版本控制方面的价值:

        是的,这不是我第一次使用GitHub,即使是一个人编写代码,我也能很清楚的比较出我的项目每次修改的位置,修改了什么地方,何时修改,而多人协作过程中GitHub的使用更是十分方便,可以简单的帮助大家管理代码,非常方便。

关于CMU和MIT的作业,你有何感受:

        实验的量较为适中,但这样将多个实验挤压在一起效果并不是很理想,由于即将考试,我也是急忙完成了实验部分,希望可以向世界一流大学的计算机专业学习!

关于本实验的工作量、难度、deadline:

        工作量较为适中,但希望可以更早的进行实验讲解,这样能有更长的时间完成实验,对于没接触过java或git的同学,这个实验的难度实际并不低,而且难度并不在于程序本身,而是很多知识储备,deadline有些较早。

关于初接触“软件构造”课程:

        软件构造的课程知识体系很大,是一门很新鲜的课程,是从软件层面去理解程序,和CSAPP这样从机器的角度不同,软件构造这门课讲求的是功能强大完备,算无遗策,是一门难度很高很复杂的课程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
碰撞检测是指在游戏或者模拟中检测两个物体是否发生了碰撞。在网页开发中,我们可以使用JavaScript实现简单的碰撞检测。在01-object-hit-test.html中,实现了一个基于Canvas的简单碰撞检测示例,通过判断两个圆形物体之间的距离是否小于它们的半径之和来判断它们是否发生了碰撞。 具体实现步骤如下: 1. 定义两个圆形物体(对象),包括其位置、半径、颜色等属性。 ``` var circle1 = { x: 100, y: 100, r: 50, color: "#FF0000" }; var circle2 = { x: 200, y: 200, r: 80, color: "#0000FF" }; ``` 2. 在Canvas中绘制两个圆形物体。 ``` ctx.beginPath(); ctx.arc(circle1.x, circle1.y, circle1.r, 0, 2 * Math.PI); ctx.fillStyle = circle1.color; ctx.fill(); ctx.beginPath(); ctx.arc(circle2.x, circle2.y, circle2.r, 0, 2 * Math.PI); ctx.fillStyle = circle2.color; ctx.fill(); ``` 3. 计算两个圆形物体之间的距离。 ``` var distance = Math.sqrt(Math.pow(circle1.x - circle2.x, 2) + Math.pow(circle1.y - circle2.y, 2)); ``` 4. 判断两个圆形物体是否发生碰撞。 ``` if (distance < circle1.r + circle2.r) { console.log("Collision detected!"); } ``` 完整代码如下: ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Object Hit Test</title> </head> <body> <canvas id="canvas" width="400" height="400"></canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var circle1 = { x: 100, y: 100, r: 50, color: "#FF0000" }; var circle2 = { x: 200, y: 200, r: 80, color: "#0000FF" }; ctx.beginPath(); ctx.arc(circle1.x, circle1.y, circle1.r, 0, 2 * Math.PI); ctx.fillStyle = circle1.color; ctx.fill(); ctx.beginPath(); ctx.arc(circle2.x, circle2.y, circle2.r, 0, 2 * Math.PI); ctx.fillStyle = circle2.color; ctx.fill(); var distance = Math.sqrt(Math.pow(circle1.x - circle2.x, 2) + Math.pow(circle1.y - circle2.y, 2)); if (distance < circle1.r + circle2.r) { console.log("Collision detected!"); } </script> </body> </html> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值