软件构造实验一报告

 

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

3.4 Tweet Tweet 3

3.4.1 Problem 1: Extracting data from tweets. 3

3.4.2 Problem 2: Filtering lists of tweets. 3

3.4.3 Problem 3: Inferring a social network. 3

3.4.4 Problem 4: Get smarter 3

4 实验进度记录.... 3

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

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

6.1 实验过程中收获的经验和教训... 4

6.2 针对以下方面的感受.... 4

 

 

  1. 实验目标概述

本次实验通过求解四个问题,训练基本 Java 编程技能,能够利用 Java OO 开

发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够

为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。

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

⚫ 基本的 Java OO 编程

⚫ 基于 Eclipse IDE 进行 Java 编程

⚫ 基于 JUnit 的测试

⚫ 基于 Git 的代码配置管理

  1. 实验环境配置

在本地机器安装相应的开发环境JDK、Eclipse、Git

并在自己的Eclipse IDE中安装配置Junit

了解如何使用JUnit为Java程序编写测试代码并执行测试

没有遇到问题,一切都很顺利。

地址:https://github.com/ComputerScienceHIT/Lab1-1170300724

  1. 实验过程
    1. Magic Squares

魔术方格的问题只需要每行,列和对角线的总和相等,它不要求总和是特定值,读入的文件要求数字间以\t分割且都是正整数

      1. isLegalMagicSquare()

首先初始化一个List>二维List以存储矩阵,从文件中读取txt里面的数据,存入到二维List中。在这个步骤中检测是否含有非法字符,是否是/t,是否是空。读取完成后验证该矩阵是否为方阵,如果不是,输出错误并返回false,最后再分别计算各行、各列以及对角线之和,如果相等,则为Magic Square,否则不是,输出错误并返回false。

      1. generateMagicSquare()

给出的代码使用Merzirac法生成奇阶幻方:

首先向第一行正中的方格内填写1

以下依次向右上角的方格内填写234……

若右上角的方格内已经有数字,则向下移动一格继续填写

若右上角的方格超出矩阵的行,则移到矩阵下一列的最下端继续填写

若右上角的方格超出矩阵的列,则移到矩阵下一行的最左端继续填写

    1. Turtle Graphics

徽标是在麻省理工学院创建的一种编程语言,最初用于在空间中移动机器人。添加到徽标语言中的Turtle图形允许程序员向屏幕上的“乌龟”发出一系列命令,这些“乌龟”会移动,随着它划一条线。Turtle图形也被添加到许多不同的编程语言中,包括Python,它是标准库的一部分。

      1. Problem 1: Clone and import

在本地创建一个workplace,在老师给的链接里面下载下来全部代码,放到工作台里进行编辑。

      1. Problem 3: Turtle graphics and drawSquare

这个问题要求使用现有的turn和forward,画一个正方形,就走两步转90度最后转出个正方形就可以了

      1. Problem 5: Drawing polygons

需要用到calculateRegularPolygonAngle()和drawRegularPolygon()。calculateRegularPolygonAngle()是给正多边形边数,计算正多边形内角1

有一个小问题就是int和double之间需要进行转换,可以用多种方法解决。drawRegularPolygon()是根据给出的多边形边数,直接画出来一个多边形。只需要调用alculateRegularPolygonAngle()计算出内角,再转换出外角,就可以画出来一个正多边形,具体步骤和画正方形没有什么区别。画正方形也可以调用这个函数,然后把边数设为4.

 

Problem 6: Calculating Bearings

需要用到calculateBearingToPoint()和calculateBearings()方法要保证这两个功能函数是对的。calculateBearingToPoint()是计算有一个初始方向时,想要指向一个给定点的时候,需要顺时针旋转的角度。传入的参数有现在的角度,和点的XY值。当前朝向的度数以向上方为0度。主要是利用正切tan来进行计算。calculateBearings()方法的参数为两个List,第一个List中为X的值,第二个为Y的值,需要返回一个List,包含所有需要转动的角度。只需要遍历两个集合,调用calculateBearingToPoint()方法即可,可设置一个变量记录当前朝向的角度。

      1. Problem 7: Convex Hulls

这道题主要是要实现凸包算法。在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。X的凸包可以用X内所有点(X1,...Xn)的凸组合来构造。根据测试用例,就是在给定的point类型的点中,找到一个最小的凸包。由于是最小的凸包,如果同一条直线上的多个点都是凸包边界上的点,只取两端的点以保证最小。这里使用了扫描算法。

由最底的一点 p1p1 开始(如果有多个这样的点,那么选择最左边的),计算它跟其他各点的连线和 x 轴正向的角度,按小至大将这些点排序,称它们的对应点为 p2,p3,...,pnp2,p3,...,pn。这里的时间复杂度可达 O(nlogn)O(nlog⁡n)

 

以下图为例,基点为H,根据夹角由小至大排序后依次为H,K,C,D,L,F,G,E,I,B,A,J。下面进行逆时针扫描。

https://images2018.cnblogs.com/blog/1182370/201808/1182370-20180822120518547-1428894341.png

线段<H, K>一定在凸包上,接着加入C。假设线段<K, C>也在凸包上,因为就H,K,C三点而言,它们的凸包就是由此三点所组成。但是接下来加入D时会发现,线段<K, D>才会在凸包上,所以将线段<K, C>排除,C点不在是凸包上。

即当加入一点时,必须考虑到前面的线段是否会出现在凸包上。从基点开始,凸包上每条相临的线段的旋转方向应该一致。如果发现新加的点使得新线段与上线段的旋转方向发生变化,则可判定上一点必然不在凸包上。实现时可用向量叉积进行判断,设新加入的点为 pn+1pn+1,上一点为 pnpn,再上一点为 pn−1pn−1。顺时针扫描时,如果向量 <pn−1,pn><pn−1,pn> 与 <pn,pn+1><pn,pn+1> 的叉积为正,则将上一点删除。

删除过程需要回溯,将之前所有叉积符号相反的点都删除,然后将新点加入凸包。

      1. Problem 8: Personal art

采用了随机数算法,让这一切随缘发生,前进大小和旋转角度都是随缘的。为了稍微好看一点,采用了随机变换颜色,有点像拿笔瞎画的。

      1. Submitting

在项目的根目录打开终端,使用git add .命令将所有文件的改变存储在暂存去,再使用git commit -m “提交内容”将暂存区的内容提交到本地的版本库,创建一个新的版本。最后使用git push origin master将本地版本库的master分支推送到远程服务器(origin)的master分支上,这里的远程服务器就是GitHub的服务器。

    1. Social Network

要求实现一个模拟的社交网络,形成一个图结构,可以向图中添加点(人)和边(关系),并且可以计算各个点之间最短的距离。

      1. 设计/实现FriendshipGraph类

FriendshipGraph是这道题的主要类,用来算距离和输出。主要是描述图,所以采用了更方便描述距离的邻接矩阵的方法。根据给出的格式要求,该类需要实现addVertex()方法、addEdge()方法和getDistance()方法。addVertex()方法用于向图中添加一个点,需要检测加入的点是否重复,如果重复需要跳出,加入之后还需要对矩阵进行变化。addEdge()是在两个点中加入一条边,说明他俩有关系,根据题意,加入的是一条有向边,双向关系需要addEdge()两次相反的点。getDistance()方法用于计算两个点之间点最短距离。由于有向路的权值都为1,仅需要采用广度优先遍历,记录遍历的层次即可,遍历到目标点时到层次即为最短的距离。

      1. 设计/实现Person类

类似结构体。只要添加属性就可以了。

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

word里面的main复制进来,运行测试结果,与word中相同。

      1. 设计/实现测试用例

共测试两个方法:getDistance()方法和addVertex()方法。getDistance()测试是否可以得到合理的输出。addVertex()主要测试当添加相同的人时抛出异常。

    1. Tweet Tweet

该试验对一些Twitter进行基础的分析,根据twitter找出关注关系

      1. Problem 1: Extracting data from tweets

对tweet进行分析。getTimespan()和getMentionedUsers实现,并且通过测试。getTimespan()的功能是找出一堆tweet中的时间差,传入是List里面有好几个tweet语句,其中时间是Instant类,通过百度,发现这个类有个方便的函数可以直接计算出时间差,所以只要找出时间最早最晚的两个tweet做时间差就可以了。getMentionedUsers()用于找出tweets中被提到(@)的其它用户。利用正则表达式进行判断,\\W@([\\w,-]+)应该用这个。遍历tweets,使用该正则表达式进行匹配,并将结果存入List,返回即可。

      1. Problem 2: Filtering lists of tweets

这是要求对tweet进行分析。要求实现writtenBy()、inTimespan()和containing()方法。writtenBy()是找出tweet的作者,利用getAuthor()找出每个tweet的作者,然后与给定的username进行比较返回找到的作者。inTimespan()是找出相应时间中写出的tweet。利用函数找到相应的时间段里的tweet,再通过getTimestamp()方法获得该tweet的时间,将两个时间进行比较。containing()要找到指定词的tweet,利用正则表达式遍历所有的tweet,返回找到的那个tweet即可。

      1. Problem 3: Inferring a social network

还是对tweet进行分析,但是要分析好几个。要写完guessFollowsGraph()和influencers()方法。guessFollowsGraph()方法返回一个Map,规则是@的前面关注了后面的人。用Filter.getMentionedUsers()找出@提到的人。influencers()方法要求对影响力进行降序排序。可遍历Map。新建一个容器存储被提到的人的次数,再进行排序输出就可以了。

      1. Problem 4: Get smarter

将@功能进行了改进,让A@B变成了双向关注。

  1. 实验进度记录

请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。

每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。

不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。

日期

时间段

任务

实际完成情况

2019-02-27

15:45-17:30

编写问题1并进行测试

按计划完成

2019-03-02

12:00-17:30

编写问题2并进行测试

按计划完成

2019-03-05

11:45-17:30

编写问题3并进行测试

按计划完成

2019-03-10

12:00-18:00

编写问题4并进行测试

按计划完成

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

遇到的难点

解决途径

 

凸包一直遇到奇怪的问题,无法根据算法输出正确结果

 

 

优化了输入极角相同时的计算

 

问题4遇到分析问题

 

百度到了正则表达式

  1. 实验过程中收获的经验、教训、感想
    1. 实验过程中收获的经验和教训

学习了java的基础编程和Junit的测试。学会了凸包算法和正则表达式。

    1. 针对以下方面的感受

Java太难了,学过的都忘记了。Git并没有使用到实际作用,Gitclassroom还导致了更多问题出现。实验工作量大,但时间充裕,不过经常会被其他事情打断实验过程,不能流畅进行思考。

猜你喜欢

转载自blog.csdn.net/qq_41903930/article/details/88640743