目录

1 实验目标概述

2 实验环境配置

3 实验过程

3.1 Magic Squares

3.2 Turtle Graphics

3.3 Social Network

1.实验目标概述

1.1本次实验通过对幻方,海龟画图以及社交网络三个问题的求解,训练基本 Java 编程技能,能够利用 Java OO 开发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够 为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。

1.2利用 Git 作为代码配置管理的工具,学会 Git 的基本使用方法。

  2.实验环境配置

2.1我们首先需要做安装java,在网页搜索java,安装jdk,之后安装java的集成开发环境Eclipse,最后配置环境变量。

具体请看:

(8条消息) java环境变量 的配置与详解(全网最详细教程)_S-D-C-L-Yourn的博客-CSDN博客_java环境变量https://blog.csdn.net/qq_41436122/article/details/82620080?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165200854716781685315384%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165200854716781685315384&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-82620080-null-null.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=java%E9%85%8D%E7%BD%AE%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F&spm=1018.2226.3001.4187

2.2由于在本次实验中我们需要用到Junit,所以必须配置Junit。可以参考下文:

(8条消息) 在Eclipse中使用JUnit4进行单元测试(初级篇)_andycpp的博客-CSDN博客_junit单元测试https://blog.csdn.net/andycpp/article/details/1327147?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165201046416780357294822%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165201046416780357294822&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-3-1327147-null-null.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=eclipse%E4%BD%BF%E7%94%A8junit%E6%B5%8B%E8%AF%95&spm=1018.2226.3001.4187

  3.实验过程

3.1Magic Squares

本实验首先要求我们要对文件输入的数据进行判断,判断其是否为幻方,而判断的标准是(1)数据是否以矩阵的方式存储;(2)矩阵每行,每列,还有左右对角线之和是否都相等;(3)矩阵中的数字是否都是正整数;(4)矩阵每行各元素之间是否是以制表符\t隔开。这就需要我们从文件中读取数据并用合适的结构存储,之后进行判断。

其次我们需要对罗伯法生成幻方作以理解说明,并对通过罗伯法生成幻方时产生的异常作以处理,并利用罗伯法生成一个奇数阶幻方并存储测试。

3.1.1isLegalMagicSquare()

这个方法需要我们从文件中读取数据并判断数据是不是一个幻方。我们可以分两步完成。

(1)首先我们要从文件中读出数据。

这点可以参考下文:

(8条消息) java从文件中读取数据的几种方法(Java io基础)_南风知易✓✓✓的博客-CSDN博客_java读取文件内容https://blog.csdn.net/tianynnb/article/details/121185052?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165200944616782248519271%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165200944616782248519271&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-121185052-null-null.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=java%E4%BB%8E%E6%96%87%E4%BB%B6%E4%B8%AD%E8%AF%BB%E5%8F%96%E6%95%B0%E6%8D%AE&spm=1018.2226.3001.4187

(2)在保存好从文件读取的数据之后,我们开始判断它是否满足我们的判定条件。

第一步我们将line数组的每一个字符串利用\t划分成一个个小字符串并存储在String数组strings中,划分出来的每一个字符串都是一个矩阵的元素,由于strings的大小代表数据阵列的列数,line的大小代表数据阵列的行数,所以我们可以通过比较strings和line的大小判断它是否是一个矩阵。

第二步我们利用mathches()方法对strings中的每一个字符串进行正则表达式匹配,使用matches("[0-9]+")可以判断每一元素是否都是非负整数,再通过Integer.valueOf(strings[k])!=0判断是否是正整数,在判断完第一,二步之后,我们使用Integer.valueOf(strings[k])将每一个字符串转变为整型数。

int [][]data=new int[line.length][line.length];for(int j=0;j<line.length;j++)
{String[] strings=line[j].split("\t");if(strings.length!=line.length)//对每个数据之间是否是\t以及是否行列数相等的判断              return false;for(int k = 0;k<strings.length;k++)
{if(strings[k].matches("[09]+")&&Integer.valueOf(strings[k])!=0)//对每个数据是否是正整数的判断data[j][k] = Integer.valueOf(strings[k]);else                                   return false;}
}

第三步我们进行矩阵的每一行,每一列,左右对角线之和是否相等的判断。我们只需要两个for循环就可以计算出上述的求和结果,再经过一个for循环就可以判断是否相等。

3.1.2generateMagicSquare()

(1)罗伯法首先只能生成奇数阶幻方,不然在生成过程中数组会越界产生异常。它的具体生成过程是先在第一行的正中央放置1,再从这个格子开始,依次向该格子的右上方的格子放置下一个数,如果当前格子在第一行,那么把最后一行看作是第一行的上一行再放置数字,如果当前格子在最右列,那么把最左列看作是最右列的右列再放置数字,如果我们下一个要放置数字的格子已经放置了数字,我们在当前格子的下一行的相同列数的格子中开始放置数字,按照这种规则,我们就可以把1到N2的数字放置在N2个格子中生成一个N阶幻方。

(2)之后我们将生成的幻方存储在文件中,这里我们直接使用FileWriter类进行写文件的操作。

可以参考下文:

(8条消息) Java将数据信息写入文件文件的几种实现方法_Running-小猛的博客-CSDN博客_java将数据写到文本https://blog.csdn.net/leying521/article/details/85234096?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165200978916781667832496%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165200978916781667832496&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-8-85234096-null-null.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=java%E5%90%91%E6%96%87%E4%BB%B6%E4%B8%AD%E5%86%99%E5%85%A5%E6%95%B0%E6%8D%AE&spm=1018.2226.3001.4187

3.2Turtle Graphics

3.2.1Problem : Calculating Bearings

这个问题需要我们计算轴承,首先我们需要知道需要计算什么,即计算给出的点之间的角度偏移量。这个方法给出了一组点的x坐标和一组点的y坐标,我们首先得到坐标组大小,如果坐标组个数为0,我们直接返回一个空的list<Double>集合,如果坐标组个数大于0,我们通过计算返回一个坐标组元素个数减一个元素的list<Double>集合。

我们在计算在返回集合的元素的时候需要借助calculateBearingToPoint方法计算两个点之间的角度偏转,我们可以用两个int类型的临时变量m,n来保存数据,使用for循环遍历list集合完成计算。其中n首先记录第一个点的偏转方向,即0,之后在循环中来暂存计算出的偏转方向,然后加入list集合,在之后一次的循环中用m来暂存n,将m带入 calculateBearingToPoint方法参与计算。

public static List<Double> calculateBearings(List<Integer> xCoords, List<Integer> yCoords) {//throw new RuntimeException("implement me!");List<Double> result = new ArrayList<>();int x=xCoords.size();double n=0;for(int i=0;i<x-1;i++){double m=n;n=calculateBearingToPoint(m,xCoords.get(i),yCoords.get(i),xCoords.get(i+1),yCoords.get(i+1));result.add(n);}return result;}

3.2.2Problem : Convex Hulls

在这个问题中我们需要计算给出一堆点中的凸包,即一堆点中最外侧点的集合。

我们可以先判断给出点集的个数,如果给出的点集个数小于3,那么我们直接返回这个点集。之后我们开始寻找点集之中最左下角的点,我们使用pointMinjilu第一个点,之后遍历后面的所有点,如果有一个点在它的左边我们就用这个点替换最初的pointMin,如果有一个点在pointMin的下方,我们也替换这个点,遍历完之后我们得到了最左下方的点。

得到最左下方的点之后,我们将它加入list集合,之后开始循环,每次循环时遍历点集,寻找下一个我们要加入的点,每一次循环找到一个点,记为pointNext,意为要加入list集合的的点,直到找到我们最开始得到的pointMin结束循环。如果要遍历的点是pointNext本身,我们直接跳过,如果不是,我们借助calculateBearingToPoint()计算pointNext和这个点的角度偏转量,再计算两点之间的距离,如果比我们之前计算的角度偏转量(初始设为360)小,我们直接将这个点视为新的pointNext,然后将它的角度偏转量记为新的角度偏转量,将它与之前的pointNext之间的距离视为新的距离,开始下一次遍历看这个点是否会被替换。如果比我们之前计算的角度偏转量(初始设为360)大,我们开始比较这两点的距离和我们之前的得到的距离(初始为最大值),如果现在两点间的距离大于之前的距离,我们重复替换操作,开始下一次遍历。

3.2.3Problem : Personal art

在这个问题中,我尝试使用turtle画图程序画出一系列的圆,只要每次偏转固定的角度,再选择合适的长度,就可以实现画圆。我在画布的上下左右各画出两个半径不一的圆,得到组合图形。

3.2.4Submitting

可以参考下文下载git:

(8条消息) Git 详细安装教程(详解 Git 安装过程的每一个步骤)_mukes的博客-CSDN博客_git安装https://blog.csdn.net/mukes/article/details/115693833?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165201034516782246496758%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165201034516782246496758&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-115693833-null-null.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=git&spm=1018.2226.3001.4187可以参考下文使用:

(8条消息) 关于Git这一篇就够了_17岁boy想当攻城狮的博客-CSDN博客https://blog.csdn.net/bjbz_cxy/article/details/116703787?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165201034516782246496758%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165201034516782246496758&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-116703787-null-null.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=git&spm=1018.2226.3001.4187

3.3Social Network

本问题类似于图的问题,要求我们将一个Person类看成一个点,点与点之间用某种关系当作边连接起来,再来寻找两点间的最短距离。由于这个题本身是无向图,但是实验要求我们必须要可以改进为有向图,所以我们在建立边的时候就要注意方向的问题。

案例实验代码:

1. FriendshipGraph graph = new FriendshipGraph();
2. Person rachel = new Person("Rachel");
3. Person ross = new Person("Ross");
4. Person ben = new Person("Ben");
Lab Manuals for Software Construction Lab-1 Fundamental Java Programming and Testing
6
5. Person kramer = new Person("Kramer");
6. graph.addVertex(rachel);
7. graph.addVertex(ross);
8. graph.addVertex(ben);
9. graph.addVertex(kramer);
10.graph.addEdge(rachel, ross);
11.graph.addEdge(ross, rachel);
12.graph.addEdge(ross, ben);
13.graph.addEdge(ben, ross);
14.System.out.println(graph.getDistance(rachel, ross));
//should print 1
15.System.out.println(graph.getDistance(rachel, ben));
//should print 2
16.System.out.println(graph.getDistance(rachel, rachel));
//should print 0
17.System.out.println(graph.getDistance(rachel, kramer));
//should print -1

3.3.1设计/实现FriendshipGraph类

我们首先看案例代码,这里面在FriendshipGraph类中有添加点,添加边和计算距离的操作,所以我们首先要有一个点集,我们用List<Person> VertexList来实现,之后我们用addVertex方法添加点,如下图:

public boolean addVertex(Person people) //加入点集{if(VertexList.contains(people)){System.out.println("已经存在!\n ");return false;}else{VertexList.add(people);return true;}       }

有了点,我们再来看边,要添加边,我们首先要知道边的两个端点,我们用一个FindPosistion方法表示一个点在我们设置的点集中的位置,返回一个整型数,我们在addEdge方法中用这个整型数带入Person类中的Socialadd方法,给边的前端点增加与后端点的联系,以此来实现我们添加边的功能。如下图:

public int FindPosistion(Person people)
//寻找点在点集中的位置,若不在返回-1{if(VertexList.contains(people))for(int i=0;i<VertexList.size();i++)if(VertexList.get(i).equals(people))return i;return -1;
}

最后我们来看如何计算两点间的最短距离,这里我们使用广度优先搜索来实现,我们需要首先建立一个Map来表示点集中每一个点距离起始点的距离,我们使用Map<Person, Integer> distance实现。之后我们建立一个队列方便后面的广度优先遍历,我们使用Queue<Integer> queue实现。同时我们还需要一个标志数组来标记一个点是否已经被搜索,我们使用boolean []visited实现。在准备工作做好后,我们开始第一步,使用first和last两个变量借助FindPosistion方法找到两点位置,之后将第一个点入队,改变状态以及输入Map的数据,然后开始广度优先搜索,可以参考下文:

(8条消息) 图的深度优先搜索(DFS)和广度优先搜索(BFS)及其Java实现_键盘上的钢琴师_v5的博客-CSDN博客_广度优先搜索java实现https://blog.csdn.net/daijin888888/article/details/76609895?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165201091816781685325417%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165201091816781685325417&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-76609895-null-null.142%5Ev9%5Epc_search_result_cache,157%5Ev4%5Econtrol&utm_term=%E5%9B%BE%E7%9A%84%E5%B9%BF%E5%BA%A6%E4%BC%98%E5%85%88%E9%81%8D%E5%8E%86java&spm=1018.2226.3001.4187      在搜索中,我们每次进入一个点的子节点都将子节点的距离值设置为父节点的距离值加一,直到我们遇到的点就是我们要找的last点,到这里我们直接结束遍历,返回结果。其中currentvertex是我们返回的队首节点,visitnode是currentvertex的子节点:

while(!queue.isEmpty()){int currentvertex=queue.remove();for(int i=0;i<VertexList.get(currentvertex).listsize();i++)
{int visitnode=VertexList.get(currentvertex).getSocial(i);if (!visited[visitnode])
{//每次让一条边根端点到起始点的距离+1成为它的子端点的距离值,若是子端点就是目的端点退出visited[visitnode]=true;queue.add(visitnode);distance.put(VertexList.get(visitnode),distance.get(VertexList.get(currentvertex))+1);}if(VertexList.get(visitnode).equals(people2))return distance.get(VertexList.get(visitnode));}}

3.3.2设计/实现Person类

我们首先根据实验要求中的实验代码来看Person这个类要包含的信息。首先是必须要有一个字符串表示名字,我们用String name来实现。其次,我们可以看到在FriendshipGraph类中有添加点,添加边和计算距离的操作,所以这就要求我们必须在Person类中对与它相连的点作以记录,我们用一个整形变量集合List<Integer> SocialList来表示,他里面的元素代表要建立联系的点是第几个加入FriendshipGraph类中点集的点,同时我们还要有建立这个关系表的方法,我们使用Socialadd方法来实现,如下图:

public void Socialadd(int posistion)//添加联系人;{SocialList.add(posistion);}

还要有返回关系表中元素的方法,我们使用getSocial方法实现,如下图:

public int getSocial(int position) //其他联系者与person的关系;{return SocialList.get(position);}

有了点的关系,我们再来看边的关系,我们使用edgeexist方法来判断要加入的边是否已经存在,如下图:

public boolean edgeexist(int posistion)//判断两者之间是否有边;{if(SocialList.contains(posistion))return true;elsereturn false;}

有了这些方法,Person类就建立完成了。

软件构造LAB1的一些思考相关推荐

  1. 哈工大2021软件构造lab1总结

    哈工大2021软件构造lab1总结 作为软件构造的第一次实验,感觉内容本身不是很难,里面功能的实现用上学期在数据结构和算法分析两门课里学到的知识就可以解决(尽管其实已经忘没了).这次实验主要目的还是准 ...

  2. 软件构造Lab1实验总结

    软件构造Lab1实验总结 1 实验目标概述 本次实验通过求解四个问题,训练基本 Java 编程技能,能够利用 Java OO 开 发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够 ...

  3. 2022哈工大软件构造lab1小结(知识点)

    哈工大软件构造lab1小结 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 问题一 使用的库 异常处理机制 字符串内容检查 写入文件 问题二 problem 3:画一 ...

  4. HIT 2019春软件构造Lab1

    1 实验目标概述 1 2 实验环境配置 1 3 实验过程 1 3.1 Magic Squares 1 3.1.1 isLegalMagicSquare() 1 3.1.2 generateMagicS ...

  5. 哈工大软件构造lab1

    2020年春季学期 计算机学院<软件构造>课程 Lab 1实验报告 姓名 麦昌瀚 学号 190110920 班号 7 电子邮件 835889372@qq.com 手机号码 目录 1 实验目 ...

  6. 哈工大 软件构造Lab1的设计实现

    2021年春季学期 计算学部<软件构造>课程 Lab 1实验报告 目录 1. 实验目标概述 3 2. 实验环境配置 3 3. 实验过程 6 3.1 Magic Squares 6 3.1. ...

  7. 哈工大软件构造Lab1实验报告

    2020年春季学期 计算机学院<软件构造>课程 Lab 1实验报告 目录 1 实验目标概述... 1 2 实验环境配置... 1 3 实验过程... 1 3.1 Magic Squares ...

  8. HIT 软件构造 Lab1

    2022年春季学期 计算学部<软件构造>课程 Lab 1实验报告 姓名 艾浩林 学号 120L021917 班号 2003006 电子邮件 2017869860@qq.com 手机号码 1 ...

  9. HIT软件构造lab1

    目录 1 实验目标概述 1 2 实验环境配置 1 3 实验过程 1 3.1 Magic Squares 1 3.1.1 isLegalMagicSquare() 1 3.1.2 generateMag ...

最新文章

  1. 文言文编程还不够好玩?这里有个16岁高中生开发的粤语编程项目,GitHub star量600+...
  2. 如何实现一个HTML5 RPG游戏引擎——第一章,实现地图类
  3. Git Rebase教程: 用Git Rebase让时光倒流
  4. Python部署与安装
  5. php用户注册重复_php 验证用户名重复
  6. css如何实现一个小三角形,用纯css写一个常见的小三角形
  7. 【SQL Server备份恢复】数据库恢复:对page header的恢复
  8. python编程基础知识体系_【汇总】Python 编程核心知识体系
  9. 第一篇:NSOperation的概念
  10. JVM学习-StringTable字符串常量池
  11. h5前端调用android拍照功能,H5中,嵌入式webview中,调用摄像头拍照功能的实现
  12. 再战JavaScript
  13. 安卓7.0海信定制版新增功能
  14. 【渝粤教育】国家开放大学2018年春季 8639-22T食品营养与健康 参考试题
  15. 遇到问题的时候,要学会问问题
  16. 联想服务器万全T260G3系统,联想万全T260G3服务器电子教室更易管理
  17. 详述白盒测试的逻辑覆盖法的条件组合覆盖及其优缺点
  18. 动态电路中的动态元件——电容和电感
  19. 关于IE主页被篡改成2345、360、hao123等页面的说明
  20. 00.设计模式之六大原则

热门文章

  1. 各大门户免费登录入口
  2. OpenCV基础(4)使用OpenCV裁剪图像
  3. Jmeter线程组之 jp@gc - Stepping Thread Group (deprecated)
  4. python剪辑视频 裁剪_用python进行视频剪辑
  5. SVM分类,一对多;
  6. AVD的CPU的选择
  7. HHDBCS及HHDESK的资源加密功能
  8. android 第三方 im,Android基于环信SDK开发IM即时聊天
  9. Windows XP系统中如何屏蔽 Ctrl+Alt+Del、Alt+Tab以及Ctrl+Esc键序列
  10. 计算机毕业设计JAVA人民医院体检预约mybatis+源码+调试部署+系统+数据库+lw