哈尔滨工业大学hit软件构造实验lab1

1 实验目标概述

本次实验通过求解三个问题,训练以下技能:

  1. 基本的Java OO编程
  2. 基于Eclipse IDE进行Java编程
  3. 基于JUnit的测试
  4. 基于Git的代码配置管理。

2 实验环境配置

安装jdk-18:官网下载压缩包,解压。
安装git:下载安装程序,勾选在Windows命令提示符下使用Git、签出Windows样式且提交UNIX样式的行结尾、桌面快捷方式选项。
安装eclipse:最初根据教程下载了eclipse installer,但是网站给的Resource URIs无法正常使用,然后用eclipse installer安装速度太慢,就回到官网,直接下载了最新版本的Eclipse IDE for Enterprise Java and Web Developers,自带JUnit。

我的GitHub Lab1仓库的URL地址:
https://github.com/ComputerScienceHIT/HIT-Lab1-120L021328.git

3 实验过程

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

3.1 Magic Squares

3.1.1 isLegalMagicSquare()

设计思路:先进行一遍文件读取,记录下行数n,即矩阵行数,用于后续申请二维数组matrix的空间以及和每行个数比较从而判断是否满足矩阵条件;再进行一遍文件读取,读每行后,用.split方法分离这行的数据,得到本行数据个数cn,与矩阵行数n进行比较,若不相等则结束程序并报错,每个数据若不满足整数的正则表达式则也结束程序并报错,均满足则用Integer.valueOf方法处理字符串得到整数数据并存入数组matrix;最后以主对角线数据和为基准,分别与次对角线、每行、每列数据和比较,不等则返回false,均比完后,返回true。

实现过程:(只有第二步代码,一三步较简单故省略)

int rn = 0; // row number
int cn = 0; // column number
f = new File(fileName);
br = new BufferedReader(new FileReader(f));
while ((tmp = br.readLine()) != null) {
	str = tmp.split("\t");
	cn = str.length;
	if (cn != n) {
		System.out.print(
				"Error: The data in the file doesn't constitute a n order matrix or not split by '\\t'! ");
		return false;
	}
	for (i = 0; i < cn; i++) {
		if (!str[i].matches("[1-9][0-9]*")) {
			System.out.print("Error: The number(" + str[i] + ") in row " + (rn + 1) + " column " + (i + 1)
					+ " is illegal or not split by '\\t'! ");
			return false;
		}
		matrix[rn][i] = Integer.valueOf(str[i]);
	}
	rn++;
}

运行结果:
对五个txt测试文档的运行结果

3.1.2 generateMagicSquare()

设计思路:
流程图

输入偶数报错:错误类型:数组越界。因为会出现访问matrix[][n]。
输入负数报错:错误类型即原因:数组下标为负数。
实现过程:将1 ~ n2按升序依次填入二维数组:从第一行中间开始填,为了使中位数刚好在幻方正中间,从而两条对角线和也等于(n + 1) / 2;每n个数为1组;组与组之间在幻方中是上下关系,由于是从row = 0开始不断向下,所以最后一次循环结束刚好到最下面一行;组内数之间在幻方中是左下-右上关系,到达最上/右面一行则跳到最下/左面一行,类似“环”特性。
运行结果:
运行结果

3.2 Turtle Graphics

体验使用封装好的函数、编写好的JUnit测试代码,复习了直角坐标系中三角函数知识、计算凸包的Gift-Wrapping算法。

3.2.1 Problem 1: Clone and import

从GitHub获取该任务的代码:
git clone https://github.com/rainywang/Spring2022_HITCS_SC_Lab1.git
在本地创建git仓库:git init
使用git管理本地开发:git status…

3.2.2 Problem 3: Turtle graphics and drawSquare

合理调用turtle中函数即可,过程、运行结果略。

3.2.3 Problem 5: Drawing polygons

合理调用turtle中函数即可,过程、运行结果略。

3.2.4 Problem 6: Calculating Bearings

设计思路:先完成两点的之间的向量方向:用Java中Math.atan2方法,结合三角函数知识,最后判断一下使结果在0°到360°之间;再利用此函数,用循环处理一系列的点。

实现过程:

public static double calculateBearingToPoint(double currentBearing, int currentX, int currentY, int targetX,
   	int targetY) {
   double x = targetX - currentX;
   double y = targetY - currentY;
   double angle = Math.toDegrees(Math.atan2(y, x));
   angle = 90 - angle - currentBearing;
   angle = angle >= 0 ? angle : (angle + 360);
   return angle;
}
public static List<Double> calculateBearings(List<Integer> xCoords, List<Integer> yCoords) {
   List<Double> angle = new ArrayList<Double>();
   int n = xCoords.size();
   double curBearing = 0;
   int currentX = xCoords.get(0);
   int currentY = yCoords.get(0);
   for (int i = 1; i < n; i++) {
   	int targetX = xCoords.get(i);
   	int targetY = yCoords.get(i);
   	angle.add(calculateBearingToPoint(curBearing, currentX, currentY, targetX, targetY));
   	curBearing = angle.get(i - 1);
   	currentX = targetX;
   	currentY = targetY;
   }
   return angle;
}

运行结果:JUnit测试

3.2.5 Problem 7: Convex Hulls

具体实现与浅析参见另一篇博客:https://blog.csdn.net/Mechanic_PK/article/details/125213682
运行结果:见3.2.4运行结果

3.2.6 Problem 8: Personal art

设计思路:与画正多边形类似,画直线—转方向—画直线—转方向……但转的方向不是正多(四)边形外角度数,而是有所差异,从而画出“旋转感”,同时每次画直线长度增加一点点,使图像逐渐外扩而不是堆在一起。同时加上色彩变换。
实现过程:

public static void drawPersonalArt(Turtle turtle) {
   PenColor[] color = new PenColor[] { PenColor.RED, PenColor.YELLOW, PenColor.BLUE, PenColor.GREEN };
   for (int i = 0; i < 25; i++) {
   	turtle.color(color[i % 4]);
   	turtle.forward(100 + 5 * i);
   	turtle.turn(268);
   }
}

运行结果:
自由创作图形

3.2.7 Submitting

在本地仓库目录下打开Git Bash,使用命令:
git add . -->git commit -m “…” --> git push origin master

3.3 Social Network

从设计每一个class、到每一个成员、每一个函数,几乎是从0开始,最后实现一个小的项目;理解并区分public、private等访问标号对应的访问范围以及使用场景;编写JUnit测试代码并测试刚刚自己的程序。

3.3.1 设计/实现FriendshipGraph类

设计思路:用邻接表来存图,设为private,用哈希表来实现,键即点,值即与该点邻接的点;还有以下方法:建立哈希表、添加点、添加边、获取两点间距离(广搜算法)、主函数提供测试;同时为了方便后续JUnit测试时访问到该表,提供接口Graph()。
实现过程:(其余函数较简单故省略)

public int getDistance(Person p1, Person p2) {
	int distance = 0;
	LinkedList<Person> queue = new LinkedList<Person>();
	Set<Person> visited = new HashSet<Person>();
	queue.add(p1);
	visited.add(p1);

	while (queue.size() != 0) {
		int len = queue.size();
		for (int i = 0; i < len; i++) {
			Person p = queue.removeFirst();
			if (p == p2)
				return distance;
			for (Person friend : graph.get(p)) {
				if (!visited.contains(friend)) {
					queue.add(friend);
					visited.add(friend);
				}
			}
		}
		distance++;
	}
	return -1;
}

运行结果:

输出
做改动后

3.3.2 设计/实现Person类

设计思路:用字符串变量name存名字并设置为private类型,提供接口Name()来访问到该变量;提供方法来读字符串并存入name。
实现过程:略。
运行结果:见3.3.1运行结果。

3.3.3 设计/实现客户端代码main()

设计思路:添加人名、关系,并调用函数计算距离,比对与预期是否相同。
实现过程:源代码已给。
运行结果:见3.3.1运行结果。

3.3.4 设计/实现测试用例

设计思路:添加几个人名、关系,用assertEquals()方法判断程序是否正确。
实现过程:(以getDistance()为例)

@Test
public void getDistance() {
	FriendshipGraph G3 = new FriendshipGraph();
	Person a = new Person("a");
	Person b = new Person("b");
	Person c = new Person("c");
	Person d = new Person("d");
	Person e = new Person("e");
	G3.addVertex(a);
	G3.addVertex(b);
	G3.addVertex(c);
	G3.addVertex(d);
	G3.addVertex(e);
	G3.addEdge(a, b);
	G3.addEdge(b, a);
	G3.addEdge(b, c);
	G3.addEdge(c, b);
	G3.addEdge(c, d);
	G3.addEdge(d, c);
	G3.addEdge(d, a);
	G3.addEdge(a, d);
	assertEquals(0, G3.getDistance(a, a));
	assertEquals(1, G3.getDistance(a, b));
	assertEquals(2, G3.getDistance(a, c));
	assertEquals(1, G3.getDistance(a, d));
	assertEquals(-1, G3.getDistance(a, e));
}

运行结果:
JUnit测试结果

4 实验进度记录

请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
日期 时间段 任务 实际完成情况
2021-05-01、
2021-05-02、
2021-05-03 全天不定时 学习Java基本语法与框架,配置实验环境 按计划完成,但实验过程中可见效果并不好,经常有因基础不牢而出错。
2021-05-04 18:00-20:00 编写问题1的函数并进行测试 延期1小时完成
2021-05-05 13:00-20:00 编写问题2的函数并进行测试 延期一上午完成
2021-05-06 13:00-20:00 完成问题3的类、函数等并进行测试 延期2小时完成
2021-05-08 15:00-22:00 完成实验报告 按计划完成

5 实验过程中遇到的困难与解决途径

实验要求大多为英文 使用有道翻译,同时结合原文,反复理解
对文件读写等语法不够熟悉 使用CSDN、百度等查询一些方法的调用接口
P2包中的函数无法使用 上网查询后得知需要设置成Source Folder
对Gift-Wrapping算法不熟悉 在CSDN搜索相关文章并学习
初次自己构建class无从下手 请教同学、结合CSDN资料不断试验

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

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

这次实验,让我意识到基础知识要扎实,否则使用时要反复查询资料;注释要详细,代码结构要思路清晰,否则一旦出错,难以找出错误位置,同时不免有隐藏的错误而没被发现;学会了使用JUnit进行检验函数的实现正确性。

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

(1) Java编程语言是否对你的口味?与你熟悉的其他编程语言相比,Java有何优势和不足?
较好。优势为,有大量封装好的方法,为问题的处理提供许多简便、明了的思路;不足为,或许是初次使用的原因,实验环境的配置以及内部class、package等之间关系较麻烦,不像C语言那样写了代码直接编译运行就行。

(2) 关于Eclipse或IntelliJ IDEA,它们作为IDE的优势和不足;
优势为,界面更友好,运行简单快捷,提供了JUnit的包可直接导入使用;不足为需要设置Source Folder等额外操作,新手难以上手。

(3) 关于Git和GitHub,是否感受到了它在版本控制方面的价值;
感受到了,在网站上看到了每次提交的结果,可以任意的查看某版,不用担心某次不当修改出现了新的bug,而找不到上一版较好的代码。

(4) 关于CMU和MIT的作业,你有何感受;
有难度有挑战,同时也有趣味性,完成后很有成就感,并且收获很多实用的宝贵经验。

(5) 关于本实验的工作量、难度、deadline;
工作量合适,难度中等,deadline略早。
(6) 关于初接触“软件构造”课程;
课程极富趣味性与实践性,使用Java时与以往编程思路有所不同,引入了“对象”思想,但是程序调试过程依然艰辛,完成时依然十分有成就感。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值