目录
1 实验目标概述... 1
2 实验环境配置... 1
3 实验过程... 1
3.1 Magic Squares. 1
3.1.1 isLegalMagicSquare(). 1
3.1.2 generateMagicSquare(). 3
3.2 Turtle Graphics. 6
3.2.1 Problem 1: Clone and import 6
3.2.2 Problem 3: Turtle graphics and drawSquare. 7
3.2.3 Problem 5: Drawing polygons. 8
3.2.4 Problem 6: Calculating Bearings. 8
3.2.5 Problem 7: Convex Hulls. 9
3.2.6 Problem 8: Personal art 11
3.2.7 Submitting. 11
3.3 Social Network. 11
3.3.1 设计/实现FriendshipGraph类... 12
3.3.2 设计/实现Person类... 13
3.3.3 设计/实现客户端代码main(). 13
3.3.4 设计/实现测试用例... 14
4 实验进度记录... 14
5 实验过程中遇到的困难与解决途径... 15
6 实验过程中收获的经验、教训、感想... 15
6.1 实验过程中收获的经验和教训... 15
6.2 针对以下方面的感受... 15
本次实验通过求解三个问题,训练基本 Java 编程技能,能够利用 Java OO 开发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。另一方面,利用 Git 作为代码配置管理的工具,学会 Git 的基本使用方法。
l 基本的 Java OO 编程
l 基于 Eclipse IDE 进行 Java 编程
l 基于 JUnit 的测试
l 基于 Git 的代码配置管理
在这里简要概述你对该任务的理解。
isLegalMagicSquare()表面上是个对行、列、对角线求和算数判断是否是幻方的问题,实际上则一方面考察文件操作,包括如何从文件里读输入流、输入流产生的字符串如何分割,分割后如何转换为数据存入矩阵,另一方面考察矩阵合法性检验,这里就要对各种如矩阵行列数不等、输入非法数据等情况一一做检验。不合法的情况报错并返回false。最后是幻方的返回true。
而generateMagicSquare()的关键任务是将生成的矩阵写入文件,并对输入n的合法性做检查,然后判断文件里的生成矩阵是否是合法幻方。
按步骤给出你的设计和实现思路/过程/结果。
Step1:将数据从文件中读入
将输入流中的每个字符依次读取并连接成一个字符串s,在读取的过程中要判断是否有非法分隔符空格,若有空格报错并返回false。
Step2:此时文件中所有字符都顺序存在字符串s里,先后通过.split()方法以行分隔符’\n’和‘数据间分隔符\t’对字符串进行分割,第一次分割得到一维数组,记录该数组维数即为行数,第二次分割得到二维数组,
若行列数不相等,则报错返回false,
记录每行用制表符分割的维数并与第一行维数进行比较,若不相等就报错,返回false
Step3:分割后的二维数组数组元素是整数的String表示,首先通过正则表达式匹配方式判断其是否是正整数表示,若合法,我们直接通过.valueOf方法将其转换成整型存入matrix,若不合法,报错并返回false。
Step4:此时矩阵合法性以检验完毕,开始检验是否是合法幻方,分别计算每行、每列、左右对角线元素和并放入Hashset,hashset中元素是唯一的,若最后hashset元素个数为1则说明这些和都相等,否则,不是幻方。
结果:
首先检验输入n的合法性,n不能为偶数或小于0,否则报错并返回false
创建新文件6.txt
进行generateMagicSquare(),将生成的矩阵写入6.txt
生成成功,返回true
用islegalMagicSquare对生成的矩阵进行检验
结果:
偶数时,生成失败
输入奇数,生成成功并返回矩阵
成功写入6.txt
这个任务给了一个框架,我们的任务是实现turtlesoup中定义的方法,并完成junit中的测试。
如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。
首先进入实验手册中提供的仓库地址,下载代码,并导入eclipse中
在本地创建git仓库:
创建成功
Easy,只需让turtle向前爬行,然后转90度,重复操作四次,就出现了正方形
有了正方形的铺垫,画正多边形也易如反掌,首先,根据正多边形外角和恒为360度的定理,算出正多边形的内角。
然后海龟先向前爬行,转外角,即180度-内角,重复操作n(正多边形边数)次,得到正多边形。
X坐标关系 |
Y坐标关系 |
angle |
currentX==targetX |
currentY==targetY |
0 |
currentX==targetX |
currentY>targetY |
180.0-currentBearing |
currentX==targetX |
currentY |
360.0-currentBearing |
currentX>targetX |
currentY==targetY |
270.0-currentBearing |
currentX |
currentY==targetY |
90.0-currentBearing |
currentX>targetX |
currentY>targetY |
180.0+arctan(x/y)-currentBearing |
currentX |
currentY |
arctan(x/y)-currentBearing |
currentX>targetX |
currentY |
360.0-arctan(x/y)-currentBearing |
currentX |
currentY>targetY |
180.0-arctan(x/y)-currentBearing |
使用giftwrapping算法计算给定集合所有点的凸包,
giftwrapping算法思想:从一个起始点(选最左侧的)开始,遍历其他的点,选择那个最外侧的点,然后再以这个点为起始点,并与上一个点形成连线,遍历其他的点,选择与这条线极角最大的点,若极角相等,选距离远的点,放入凸包集合,重复此过程。
算法实现:
特殊情况:当给定点集中点个数小于3时,这些点全在凸包里,直接返回
一般情况:首先,选横坐标最小的点,若横坐标相同,选纵坐标最小的点做初始点,这样的点一定在凸包上。
如何判断极角大小:用向量叉积,若上一个寻访的点、当前寻访点、下一个寻访点叉积小于0,说明当前寻访点极角小于后者,
更新nextPoint
计算叉积:
若三点叉积等于0则共线,选取距离最远的点
计算距离
每次循环找出一个新的在凸包上的点,即为当前nextPoint值
添加至凸包集合
当遍历一圈,即lastPoint为初始点时,循环结束,返回凸包集合
结果:
从原点开始画圆,每六度一个,一共360/6 = 60个圆,由黄、绿、橘三种颜色搭配而成,中间还有白色空隙,增加了几何图形的艺术感。
同过余数不同换色
通过画一个很多边的正多边形实现视觉圆形
如何通过Git提交当前版本到GitHub上你的Lab1仓库。
建立一个社交网络,并求社交网络中任意两人的距离,本质上就是无向图的最短路径问题,每个人是图中的节点,两人的“认识”关系是图中的边,求最短路径利用广度搜索解决。
给出你的设计和实现思路/过程/结果。
成员变量:
序号 |
数据成员 |
数据类型 |
意义说明 |
1 |
vertex |
ArrayList |
FriendshipGraph中的顶点 |
2 |
INF |
static int |
用来表示两点间不连通的宏常量,定义为-1 |
方法:
序号 |
成员函数 |
函数功能 |
函数参数 |
函数返回值 |
1 |
addVertex() |
添加Person结点至FriendshipNetwork的vertex列表中 |
Person p |
Boolean |
2 |
addEdge() |
将p1加到p2认识的人中,将p2加到p1认识的人中 |
Person p1,Person p2 |
Boolean |
3 |
getDistance() |
得到两个Person之间的最短距离 |
Person p1,Person p1 |
Int |
Public int getDistance(Person p1,Person p2)的实现:使用广度搜索算法
首先定义dist数组,数组维数为顶点数,dist全部初始化为-1。
然后,分别用.indexOf()方法找到p1、p2在vertex[]中对应的下标start、end,并将dist[start]设为0。
新建一个integer队列,起点入队
当队列不空时,用.roll方法让队首元素出队并从队列中删除,遍历队首元素f每个认识的人即邻接点,如果邻接点的dist为INF,则更新其dist值为刚出队的顶点dist值+1,最后让邻接点入队。
最后返回dist[end]即为p1、p2间距离,若返回-1说明两人之间不认识
成员变量:
序号 |
数据成员 |
数据类型 |
意义说明 |
1 |
name |
String |
Person的名字 |
2 |
knowNames |
HashSet |
ta认识的人,认识的人有无重复性,故使用java.util下的Hashset表示。 |
方法:
序号 |
成员函数 |
函数功能 |
函数参数 |
函数返回值 |
1 |
getName() |
得到此Person的name |
无 |
String |
2 |
Person() |
类Person的姓名构造器 |
String name |
无 |
3 |
getKnown() |
得到此Person认识的Person们 |
无 |
Hashset |
4 |
addKnown() |
为此Person添加认识的人 |
Person p |
无 |
给出你的设计和实现思路/过程/结果。
给出你的设计和实现思路/过程/结果。
三个测试全部通过
addVertexTest : 测试是否能加入重复的Person,若加入重复,返回false,不重复正常加入并返回true
addEdgeTest :在两个顶点间加边,检查这两个点是否在图中,若不在,则返回false,在就正常加入并返回true
getDistanceTest : 检验getDistance()是否返回正确值
日期 |
时间段 |
任务 |
实际完成情况 |
2021.05.13 |
16:00-18:00 |
编写问题1的isLegalMagicSquare函数并进行测试 |
按计划完成 |
2021.5.16 |
15:00-16:00 |
完成generateMagicSquare()的写入,并检验它是否为幻方 |
按计划完成 |
2021.5.17 |
19:00-21:30 |
编写问题2的前六个子问题 |
第六个子问题任务较重,git不会用 |
2021.5.18 |
19:00-20:00 |
完成问题3的第六个问题 |
按时完成 |
2021.5.20 |
15:30-17:30 |
编写问题3的Person类、FriendshipGraph、SocialNetwork,并实现所有功能,完成给定测试 |
按计划完成 |
2021.5.20 |
21:00-21:30 |
学会git相关操作 |
在室友帮助下完成 |
|
|
|
|
2021.5.21 |
14:00-17:00 |
编写问题2的convex hull方法,并完成测试,编写问题3的测试文件 |
遇到很多困难,超时完成 |
遇到的困难 |
解决途径 |
Git、github不会用
|
努力学习各种博客,询问同学,恶补了很多命令 |
不知道怎么检验非法分隔符
|
发现文件中只有空格时非法分隔符,所以只要检查空格就行了 |
|
|
经验 哎 千万不要在最后一天提交,我是周六提交的,遇到了超级多的问题和麻烦,好在最后解决了。下次就编一点commit一次
我很喜欢
很智能
完全不懂,学了好多,打开新世界大门
比较喜欢MIT这种给框架,我来填写的实验,感觉更真实,也很有成就感
编程还好。。就是提交天啊,老师下回实验课能专门讲讲这方面的问题吗?感觉自己不懂走了很多弯路,浪费很多时间
好,希望以后再接再厉