2020年春季学期
计算机学院《软件构造》课程
Lab 1实验报告
姓名 |
|
3.1.2 generateMagicSquare(). 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.3.1 设计/实现FriendshipGraph类... 2
本次实验通过求解四个问题,训练基本 Java 编程技能,能够利用 Java OO 开 发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够 为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。 另一方面,利用 Git 作为代码配置管理的工具,学会 Git 的基本使用方法。
⚫ 基本的 Java OO 编程
⚫ 基于 Eclipse IDE 进行 Java 编程
⚫ 基于 JUnit 的测试
⚫ 基于 Git 的代码配置管理
到网站上下载安装包,由于国内网络的限制,下载非常缓慢。
下载了jdk eclipse git
搭建梯子有所改善。
Junit 4是新版eclipse自带,需要配置java的环境变量
Eclipse可以汉化,但是汉化比例较低。
创建了github账号,发现GitHub访问速度慢,通过改变system32下host文件,直接连接到ip
https://github.com/ComputerScienceHIT/Lab1-1180300604.git
请仔细对照实验手册,针对四个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但无需把你的源代码全部粘贴过来!)。
为了条理清晰,可根据需要在各节增加三级标题。
由文本输入幻方,幻方定义是首先为方形,其次行列,对角线之和均相等,
设计文件输入输出,同时需要补充调用generateMagicSquare函数,生成6.txt,并且检验是否为幻方,其中涉及到关于各种异常输入的处理,以及程序中的运行异常的处理。
根据指令读取对应的文件,将其转化存储到数组中,便利一遍数组,根据坐标,将值加和到新创建的加和数组,最后判断加和数组中是否都相等。
switch (fileName) {// 选取不同的文件作为输入流
case "1":
br1 = new BufferedReader(new FileReader("src\\P1\\txt\\1.txt"));
break; // 可选
case "2":
br1 = new BufferedReader(new FileReader("src\\P1\\txt\\2.txt"));
break; // 可选
case "3":
br1 = new BufferedReader(new FileReader("src\\P1\\txt\\3.txt"));
break; // 可选
case "4":
br1 = new BufferedReader(new FileReader("src\\P1\\txt\\4.txt"));
break; // 可选
case "5":
br1 = new BufferedReader(new FileReader("src\\P1\\txt\\5.txt"));
break; // 可选
case "6":
br1 = new BufferedReader(new FileReader("src\\P1\\txt\\6.txt"));
break; // 可选
default: // 可选
break;
}
这里使用switch
其实可以用“+”来组合文件名字符串这样可以减少代码量。
double l_to_r = 0, r_to_l = 0;
double[] hang = new double[edge];
double[] lie = new double[edge];
for (i = 0; i < edge; i++) {// 创建两个数组代表每行每列之和 扫描分组属于列或者行或者斜线
for (j = 0; j < edge; j++) {
hang[i] = hang[i] + num[i][j];
lie[j] = lie[j] + num[i][j];
if (i == j) {
l_to_r = l_to_r + num[i][j];
}
if (i + j == edge - 1) {
r_to_l = r_to_l + num[i][j];
}
}
}
空间换时间,扫描一遍得到加和数组
劳伯法生成奇数阶幻方
把1(或最小的数)放在第一行正中;
每一个数放在前一个数的右上一格;若该数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;若该数数所要放的格已经超出了最右列那么就把它放在最左列,上一行;若该数所要放的格已经超出了顶行且超出了最右列,则放在底行左列;若该数所要放的格已经有数填入,那么就把它放在前一个数的下一行同一列的格内
try {
File file = new File("src\\P1\\txt\\6.txt");
if(!file.exists()){
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fileWriter);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
bw.write(Integer.toString(magic[i][j]));
if (j!=n-1)
bw.write("\t");
// 有try-with-resources或者 close()关闭文件,否则数据就不能正常地保存
}
bw.write("\n");
}
bw.close();
System.out.println("finish");
} catch (IOException e) {
e.printStackTrace();
}
在原来的基础上加上文件操作,把输出移动到文件。同时增加异常处理中断,当输入是偶数或者不符合规定合理的输出。
首先需要获取源代码,然后创建和管理本地仓库。画正方形、据内角求边数、据边数求内角,画正多边形,计算方位,计算凸包,个性创作。
如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。
Git Clone 网址到文件夹
编写完成以后
Git add .
Git commit -m”备注”
Git push -u origin master
Push到github
-
-
- Problem 3: Turtle graphics and drawSquare
-
turtle.forward(60);
turtle.turn(90);
turtle.forward(60);
turtle.turn(90);
turtle.forward(60);
turtle.turn(90);
turtle.forward(60);
turtle.draw();
利用多边形相关公式
return (double) (sides - 2) * 180 / (double) sides;
return (int) Math.round(360.0 / (180.0 - angle));
由边算角由角算边
1. double degree = Math.toDegrees(Math.atan2((targetY - currentY), (targetX - currentX)));
degree = (90 - degree) - currentBearing;
if (degree < 0)
degree = degree + 360;
return degree;
使用math.atan2方法算出正切值从而计算出角度,然后与当前角度相减
2. List<Double> angle = new ArrayList<Double>();
int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
double tmpangle1 = 0;
double tmpangle2 = 0;
Iterator<Integer> x = xCoords.iterator();
Iterator<Integer> y = yCoords.iterator();
x1 = x.next();
y1 = y.next();
while (x.hasNext() && y.hasNext()) {
x2 = x.next();
y2 = y.next();
tmpangle1 = calculateBearingToPoint(tmpangle2, x1, y1, x2, y2);
tmpangle2 = tmpangle2 + tmpangle1;
tmpangle2 = (tmpangle2 < 360) ? tmpangle2 : (tmpangle2 - 360);
x1 = x2;
y1 = y2;
angle.add(tmpangle1);
}
return angle;
改进的针对list批量处理的方法
每次要重新计算当前指向角
核心是使用该算法
通过对三个点的横纵坐标进行运算,得出中间的一个点是否位于另外两个点的凸侧
Convexhull 算一个课壳体,内套的函数才算实际函数convexHull2该函数又调用split把点分开
cTriangle测试通过
通过一个大循环,每次turtle移动距离发生小变化,同时控制转角,然后改变颜色。
如何通过Git提交当前版本到GitHub上你的Lab1仓库。
上传到链接了远程仓库的本地仓库暂存区,
git add .
Git commit -m””
Git push -u origin master
社交网络图,该图是无向图,并且可以被扩展为有向图。A和B认识,则A与B连线,该图可扩展,加入顶点与边,存在方法能计算出图中任意两点间的最短距离,可以处理,不同的人有相同的名字,图中两点之间不存在路径,以及所求最小距离的两个点是同一个点,等异常。
由加边 加点 检测包含 测距等组成,
int getDistance (Person a,Person b)
boolean contain(Person a)
void addVertex(Person new_one)
void addEdge (Person a,Person b)
最终按照pdf上的例子做了测试
-
-
- 设计/实现Person类
-
Person类要求可以扩展的数据类型,即要求能够从无向图扩展为有向图,数据结构中朋友设定为两个即可实现有向。
private String name;
public Set<Person> friend;
public boolean visited;
public int index;
public int distance;
public Person(String name) {
this.name = name;
this.distance = 0;
this.visited = false;
this.friend = new HashSet<>();
}
public String getName(){
return this.name;
}
-
-
- 设计/实现客户端代码main()
-
首先需要实例化一个FriendshipGraph对象,创建人创建关系,打印结果
FriendshipGraph graph = new FriendshipGraph();
Person ross = new Person("Ross");
Person ben = new Person("Ben");
Person kramer = new Person("Kramer");
Person rachel = new Person("Rachel");
graph.addVertex(rachel) ;
graph.addVertex(ross);
graph.addVertex(ben);
graph.addVertex(kramer);
graph.addEdge(rachel, ross);
graph.addEdge(ross, rachel);
graph.addEdge(ross, ben);
graph.addEdge(ben, ross);
System.out.println(graph.getDistance(rachel,ross));
//1
System.out.println(graph.getDistance(rachel,ben));
//2
System.out.println(graph.getDistance(rachel,rachel));
//0
System.out.println(graph.getDistance(rachel,kramer));
//-1
}
也可改为通过键盘io读入人名建立关系,通过io,即先建立人对象
然后可建立对象之间的关系。
-
-
- 设计/实现测试用例
-
创建6个个体,创建边,验证边关系
graph.addVertex(rachel);
graph.addVertex(ross);
graph.addVertex(ben);
graph.addVertex(kramer);
graph.addVertex(KKK);
graph.addVertex(AAA);
graph.addEdge(ross, ben);
graph.addEdge(ben, ross);
graph.addEdge(ross,KKK );
graph.addEdge(KKK, ross);
graph.addEdge(KKK, AAA);
graph.addEdge(AAA, KKK);
graph.addEdge(rachel, ross);
graph.addEdge(ross, rachel);
assertEquals(-1,graph.getDistance(rachel,kramer));
assertEquals(3,graph.getDistance(rachel,AAA));
assertEquals(2,graph.getDistance(ben,KKK));
assertEquals(1,graph.getDistance(rachel,ross));
assertEquals(2,graph.getDistance(rachel,ben));
assertEquals(0,graph.getDistance(rachel,rachel));
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 | 时间段 | 任务 | 实际完成情况 |
2020-02-25 | 14:00-15:30 | 编写问题1的isLegalMagicSquare函数并进行测试 | 按计划完成 |
2020-02-28 | 19:00-00:30 | 完成P1 | 延期1小时完成 |
2020-03-4 | 19:00-00:30 | 完成P2 | 按计划完成 |
2020-03-5 | 19:00-00:30 | 完成P2 | 按计划完成 |
2020-03-10 | 19:00-00:30 | 完成P3 | 按计划完成 |
2020-03-11 | 19:00-00:30 | 完成P3 | 按计划完成 |
遇到的难点 | 解决途径 |
根据输入的不同的字符串,读取不同的TXT,不知道java 如何替换语句中的文件名
| 在程序中放入5个文件名,用switch语句控制 |
如何从文件中读入矩阵,如何在不使用动态数组的情况下,根据不同文件,创建不同大小的数组,并将输入字符串输入流转为数字,存放在数组里。
| 使用bufferedread类进行文件流操作,先读入一行,利用split分词转为数字,幻方横纵相等,从而根据每行数据个数创建一个数组,有效节约空间。 |
第一次运行程序报错,不会使用eclipse调试,
| 学习调试,调试程序 |
测试P1所有功能 做修正 | 发现有些矩阵中包含小数 |
测试P1所有功能 做修正 | 发现矩阵中有数字间隔不是指标符号 |
P2多边形 角度 计算公式不记得了 | 上网查找资料,使用测试文件,通过 |
P2 | 不清楚凸包的的定义,没有思路,上网查找凸包定义,慢慢逐步测试,创建一些自己编写的小测试文件,测试通以后,逐步完善,最后通过测试。 |