软件构造lab1 - 实验报告
1.实验目标概述
根据实验手册简要撰写。
2.实验环境配置
在qq群下载了Eclipse和JDK并安装, 在GitHub网站下载安装了Gitbush,
但是没有配置环境变量,在老师的帮助下得以解决。
https://github.com/ComputerScienceHIT/Lab1-1180300119
3.实验过程
3.1 Magic Squares
Magic Squares–幻方,是一种将数字安排在矩阵中,使每行、每列和正反对角线上的数字之和都相等。
3.1.1 isLegalMagicSquare()
本题要求写一个函数,判断txt文件中保存的矩阵是否符合幻方要求。输入参数为文件路径。返回为boolean类型。
首先利用传入文件路径按行读取文件内容并转为String类型;
String path = “./src/p1/txt/” + fileName;
FileReader reader = new FileReader(path);
BufferedReader in = new BufferedReader(reader);
String line;
将line用\t分割并储存在String类型数组里
String[] Str = line.split("\t");
为了方便处理,我将第一行拿出来单独处理,以第一行为基准得到行列数以及一行的和,建立二维数组,并且将划分开的每一小字符串用charAt方法逐一判断每个字符是否在0-9之间,可以排除负数,小数以及使用非’\t’其他字符输入。然后用Integer.parseInt()将字符串转为整数存入数组。
for(int i = 0; i < Str.length; i++)
{
for(int j = 0; j < Str[i].length(); j++)
{
if(Str[i].charAt(j) < ‘0’ || Str[i].charAt(j) > ‘9’)
{
System.out.println(“输入符号不满足要求”);
return false;
}
}
temp = Integer.parseInt(Str[i]);
nums[lines][i] = temp;
num += temp;
}
之后利用while循环按行读完文件,对于每行都要判断列数是否与第一行相等(为了避免数组溢出,需要加一个行数判断,在行数大于第一行列数时报错)while循环结束后应判断行数是否等于列数,如不等于,报错。
while ((line = in.readLine()) != null)
之后利用二维数组里存好数据计算每行,每列,正反对角线和判断是否为幻方。
3.1.2 generateMagicSquare()
int magic[][] = new int[n][n];
int row = 0, col = n / 2, i, j, square = n * n; //找到第一行最中间的位置放1
for (i = 1; i <= square; i++) //将1到n*n按顺序放入矩阵中
{
magic[row][col] = i; //在相应位置赋值
if (i % n == 0) //计算下一个位置
row++; //若是放置好一个斜行的元素,这开始下个斜行
else
{
if (row == 0) //如果到达第一行,就跳转到最后一行
row = n - 1;
else //否则,行数减1
row–;
if (col == (n - 1)) //如果到达最后一列,就跳转到第一列
col = 0;
else //否则列数加1
col++;
}
}
如果输入为偶数,在运行会出现数组下标越界;
如果输入为负数,会出现数组长度为负数。
3.2 Turtle Graphics
熟悉turtle Graphics的各种函数接口,调用设置好的函数,实现作图,并使用.Math库的几个函数实现一些图形相关计算计算。
3.2.1 Problem 1: Clone and import
直接从github下载实验包,在eclipse里利用ssh进行远程链接。
3.2.2 Problem 3: Turtle graphics and drawSquare
问题:画一个矩形。
解决思路:重复四次前进转弯90°。
for(int i = 0; i < 4; i++)
{
turtle.forward(sideLength);
turtle.turn(90);
}
3.2.3 Problem 5: Drawing polygons
public static double calculateRegularPolygonAngle(int sides)
问题:给出正整数sides(>2),返回正sides边形的内角度数。
解决思路:使用公式(sides - 2) * (180.0/ sides);
public static int calculatePolygonSidesFromAngle(double angle)
问题:给出浮点数angle(0<angel<180),返回以angle为内角度数的正n边形边数。
解决思路:(int) Math.round(360/(180-angle));
public static void drawRegularPolygon(Turtle turtle, int sides, int sideLength)
问题:给出边数、边长,画一个正多边形。
解决思路:调用calculatePolygonSidesFromAngle函数,求出正多边形的内角度数,然后用画正方形的方法画正多边形。
3.2.4 Problem 6: Calculating Bearings
public static double calculateBearingToPoint(double currentBearing, int currentX, int currentY, int targetX, int targetY)
问题:计算当前向量与目标向量的夹角。输入的5个参数为:当前向量方向,当前点横纵坐标,目标点横纵坐标。
当前方向由当前方向与y轴正向夹角表示,目标向量的方向同理。
解决思路:先求目标向量方向:求当前点与目标点的连线与y轴夹角的正切值:angle = (targetX - currentX) / (targetY - currentY),调用Math库的atan方法把angle转化为弧度,再用公式:角度=弧度*180/PI求得当前向量与y轴正向夹角,与当前方向作差。(角度为负数时需要通过+360的方式使其转化到0-360范围内,否则作差时可能出现错误。得到结果需要%360转化为正角。)
因为题目要求是“当前向量转过多少度后达到目标向量”,因此必须使用目标向量角度减去当前向量角度。
public static List calculateBearings(List xCoords, List yCoords)
问题:以x,y两个列表形式给出一系列点的横纵坐标。默认起始点与y轴正向夹角为0度,对于之后每一点,当前向量为前一次求出向量方向。
解决思路:调用calculateBearingToPoint函数求两点夹角,保存在列表中并返回。
3.2.5 Problem 7: Convex Hulls
public static Set convexHull(Set points)
问题:求给定一组点的最小凸包。
解决思路:运用Gift wrapping algorithm算法,因为是求最小凸包,所以每次需要选择转向角最小,同时距离最长的点。需要注意对输入点的个数进行判断,若<=2,那么可以直接返回points。
3.2.6 Problem 8: Personal art
随便画一个图形。
3.2.7 Submitting
直接在eclipse中push就好。
3.3 Social Network
填充完成Person和FriendshipGraph两个类,模拟社交网络,能够实现添加节点、节点之间添加边的功能,并且可以计算两节点之间最短路。设计/实现FriendshipGraph类。
3.3.1 设计/实现FriendshipGraph类
Set person_list = new HashSet();
List list = new ArrayList();
public void addVertex(Person new_person) throws Exception
public void addEdge(Person person1, Person person2) throws Exception
public int getDistance(Person person1, Person person1)
需要注意如果addVertex重复添加同一个名字会报错。
addEdge重复添加同一个关系也会报错。
getDistance如果person1和person2相同得到距离为0.
使用bfs非常简单没跑一次循环距离加1,遇到person2直接break,
要是没遇到返回-1。
3.3.2 设计/实现Person类
String name;
Set friend_list = new HashSet();
List flist = new ArrayList();
boolean visit;
public Person(String string)
public String get_name()
public Set get_friends()
public void add_friend(Person new_friend) throws Exception
需要注意的是如果给一个人添加重复朋友会报错。
3.3.3 设计/实现客户端代码main()
不断循环直至用户自己选择退出,用户可选择添加名字,添加关系或是查看距离。
3.3.4 设计/实现测试用例
分为3个测试案例
addVertexTest测试输入重复名字会报错
getDistanceTest测试可以正常输入名字,添加关系,以及可以正常返回距离,0,-1.
addEdgeTest测试输入重复边会报错。
4.实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
5.实验过程中遇到的困难与解决途径
6.实验过程中收获的经验、教训、感想
6.1 实验过程中收获的经验和教训
对java语言的掌握十分不足,需要编写更多代码进行适应。
6.2 针对以下方面的感受
(1)Java编程语言是否对你的口味?
很多数据结构直接可以使用非常舒服。
(2)关于Eclipse IDE
会出一些不知道怎么解决的莫名其妙的问题
(3)关于Git和GitHub
英文界面还是有很大压力
(4)关于CMU和MIT的作业
非常有意思,与现实铁警
(5)关于本实验的工作量、难度、deadline
工作量不大,主要难在对java不熟悉,建议以后将java改成必修课程。我编写的一大半时间都花在更改习惯上了。
(6)关于初接触“软件构造”课程
编程的必经之路,英语课件授课非常难受。