《软件构造》Lab 1
2021年春季学期
计算学部《软件构造》课程
Lab 1
姓名
学号
班号
电子邮件
手机号码
目录
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 编程
基于 Eclipse/IDEA IDE 进行 Java 编程
基于 JUnit 的测试
基于 Git 的代码配置管理实验环境配置
2 实验过程
请仔细对照实验手册,针对四个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但无需把你的源代码全部粘贴过来!)。
为了条理清晰,可根据需要在各节增加三级标题。
2.1 Magic Squares
要求一:从远程仓库下载五个txt,main中分别读取并判断是否为magicsquare(矩阵的每一行、每一列和对角线的数字之和都相等),若出现异常情况(文件中的数据不符合 Magic Square 的定义(行列数不相等、并非矩阵等)、矩阵中的某些数字 并非正整数、数字之间并非使用\t 分割等)在控制台输出错误类型,并返回false。
要求二:完善generateMagicSquar,使之能够产生一个magicsquare并输出到6.txt,当输入的 n 不合法时(n 为偶数、n 为负数等),提示错误输出 false 。同时用要求一的函数isLegalMagicSquare()判断生成的是否是magicsquare。
2.1.1 isLegalMagicSquare()
用spilt分割按行读的txt文档,存在String[]oneLine,这样的话将oneLine每个元素与”[0-9]+”匹配,不成功自然就是输入格式错误。
用public static boolean[] rep=new boolean[N*N+1]表示每个数字是否重复出现,在循环中将每个出现过的标记为true,这样下次遇到就可以知道重复出现了。
用colNum=0,rowNum=0表示行列号,通过列数是否变化以及行列式是否相等表示是否规范。
先比较对角线之和,再用一个两层循环变化i与j比较各行列之和。
2.1.2 generateMagicSquare()
流程图:
函数开始就判断输入是否异常,再添加写入文件功能。
2.2 Turtle Graphics
Trurtle Graphics
画正方形。
计算正多边形内角和外角
计算向量夹角
计算凸包
绘制个人图形
2.2.1 Problem 1: Clone and import
如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。
ssh -****** -t rsa -C [email protected]
ssh –T [email protected]
git config –global user.name whdsn123
git config –global user.emal [email protected]
git clone [email protected]:ComputerScienceHIT/HIT-Lab1-1190201707.git
2.2.2 Problem 3: Turtle graphics and drawSquare
已知边长,画出边长为指定数值的正方形,参数是sidelength
2.2.3 Problem 5: Drawing polygons
正多边形的内角(double)180.0−(double)360.0/sides
2.2.4 Problem 6: Calculating Bearings
turtle旋转的方向是顺时针,坐标轴角度的旋转角度的逆时针
double angle=(Math.atan2(targetY-currentY, targetX-currentX)/Math.PI)*180.0;、
angle=90-angle-currentBearing;
2.2.5 Problem 7: Convex Hulls
从x最小的点起(x相同取y最小)逐个寻找极坐标下极角最小的点,若遇到两个极角相同的点,取距离更长的,最终遇到初始点时,凸包构造完成,返回即可。
public static Set convexHull(Set points) {
//throw new RuntimeException(“implement me!”);
if(points.size()<4)
return points;
Set ans=new HashSet();
Point left=new Point(Double.MAX_VALUE, Double.MAX_VALUE);
for(Point i:points) {
if(i.x()<left.x())
left=i;
else if(String.valueOf(i.x()).equals(String.valueOf(left.x()))){
if(i.y()<left.y())
left=i;
}
}
ans.add(left);
Point temp=new Point(0,0);
Point next=new Point(0,0);
temp=left;
double correction=0.0;
//double tem;
double max=360.0;
double mul=0.0;
for(Point i:points) {
if(i!=temp) {
if((Math.atan2(i.y()-temp.y(),i.x()-temp.x())*180/Math.PI)<max) {
max=Math.atan2(i.y()-temp.y(),i.x()-temp.x())*180/Math.PI;
mul=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
next=i;
}else if((String.valueOf((Math.atan2(i.y()-temp.y(),i.x()-temp.x()))*180/Math.PI)).equals(String.valueOf(max))) {
double mul1=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
if(mul1>mul) {
next=i;
mul=mul1;
}
}
}
}
ans.add(next);
correction+=max;
temp=next;
while(temp!=left) {
double angle;
double theta;
max=360.0;
mul=0.0;
for(Point i:points) {
if(i!=temp) {
angle=Math.atan2(i.y()-temp.y(),i.x()-temp.x())*180.0/Math.PI;
if(angle==0) {
if(ans.contains(i))
theta=(angle+(360)-correction)%(360);
else
theta=(angle-correction)%360;
}else
theta=((angle<0?angle+(360):angle)-correction)%(360);
//double r=Math.sqrt(Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2));
if(theta<max) {
max=theta;
mul=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
next=i;
}else if(String.valueOf(theta).equals(String.valueOf(max))) {
double mul1=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
if(mul1>mul) {
next=i;
mul=mul1;
}
}
}
}
if(next!=left) {
ans.add(next);
correction+=max;
}
temp=next;
}
return ans;
}
2.2.6 Problem 8: Personal art
随便画了个图形>_<
2.2.7 Submitting
git add .
git commit -m " "
git push origin master
2.3 Social Network
Person和FriendshipGraph模拟社交网络,getDistance返回两人最短距离。
可以利用到邻接矩阵实现bfs广度优先搜索算法,我写的是一种类似的思路。
2.3.1 设计/实现FriendshipGraph类
用于每次调用getDistance后将是否遍历过改为false
我认为这样写更简单易懂,就像蛋卷一样一层一层向外拓展,越到外面越大,里面最中心只有一个人,每一层都代表里面一层朋友的集合(用turefalse表示是否遍历过),每一层都没有contains成功就有dis++(距离++)。
2.3.2 设计/实现Person类
构造方法中便有判断重名的代码,每个person有自己的名字、是否遍历过和一个朋友集合。
2.3.3 设计/实现客户端代码main()
指导手册的测试用例
2.3.4 设计/实现测试用例
仿照样例做的几个测试用例:
3 实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 时间段 任务 实际完成情况
2021-05-18 19:30-24:00 编写问题1的isLegalMagicSquare和generateMagicSquare函数并进行测试 按计划完成(刚开始很不熟悉eclipse)
2021-5-19 19:00-23:00 问题三构思和编写, 遇到困难,思路有问题
2021-5-21 20:00——21:40 问题三完善解决问题和写测试用例 完成
2021-5-23 白天大部分时间 主要在写凸包问题的代码,以及学习git的使用 完成
4 实验过程中遇到的困难与解决途径
遇到的困难 解决途径
Java语法和许多函数以及eclipse的使用相当生疏
花了许多时间百度和看书
Magicsquare函数没想到如何判断数字是否重复出现
创建一个static boolean[] rep=new boolean[N*N+1]
用来表示数字n是否出现过,例如9出现一次就标记rep[9]=true;
问题三getdistance函数思路不明确
后来想到可以构建层层包围的结构,利用队列实现
凸包问题出现了许多bug,以及起始点确定问题
不断debug中发现起始点不只是x最小那么简单,应该保证y尽量小,这样便不至于有(1,1),(1,2)选择了(1,2)这样的错误。
5 实验过程中收获的经验、教训、感想
5.1 实验过程中收获的经验和教训
熟悉了eclipse使用和面向对象编程的思想,感受到了java是一门适合编写大型复杂项目的语言,注重结构,还了解了junit编写和git的使用,总体收获颇丰。
教训也很多,主要是思路不清晰导致的,希望今后能通过不断训练改进。
5.2 针对以下方面的感受
(1) Java编程语言是否对你的口味?
函数库很丰富,面向对象也挺容易构思的
(2) 关于Eclipse IDE;
刚开始很生疏,但慢慢发现不难掌握
(3) 关于Git和GitHub;
花了很长时间,感觉经常出现各种错误,可能是我掌握不到位
(4) 关于CMU和MIT的作业;
英文网页阅读有些困难,但实验本身设计感觉很好
(5) 关于本实验的工作量、难度、deadline;
对于不够熟悉java和面向对象编程的人来说任务量不小,难度一般,ddl正常
(6) 关于初接触“软件构造”课程;
感觉可能需要考虑更多设计代码结构的问题