Lab 1

1 实验目标概述

本次实验通过求解四个问题(其中一个可选),训练基本Java编程技能,能够利用Java OO开发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。另一方面,利用Git作为代码配置管理的工具,学会Git的基本使用方法。

  • 基本的Java OO编程
  • 基于Eclipse IDE进行Java编程
  • 基于JUnit的测试
  • 基于Git的代码配置管理

2 实验过程

2.1 Magic Squares

首先需要了解Magic Square的定义:一个每行、每列以及主次对角线上元素之和均相等的方阵。根据任务的要求,对于一个对Java还不是很熟练的人来说,最困难的部分在于需要从文件当中读取所需要的信息并在这个过程中过程中进行条件的判断。需要考虑浮点数以及负数的特殊情况,还需要识别出空格等特殊字符,并用异常的形式来提示,这些是该程序的主要的困难部分,编写过程中通过不断学习,学习到了一些相关的基本语法和编程手段。

2.1.1isLegalMagicSquare()

首先读取文件。首先创建一个文件类,并根据文件长度创建一个byte数组,接下来将文件内容以byte流形式读入该数组,接下来将其转化为字符串并根据/n进行分割得到字符串数组,分行处理。先根据每行大小创建一个二维数组,接下来根据这个数组判断内容,通过split分割得到的字符串进行判断。当判断为满足条件(没有特殊字符且为方阵时)进行下一步判断。
通过Square类中的Judge方法,计算第一行的和,并用接下来计算出的每行、每列和主次对角线的和进行判断,若有不同则返回假,否则即为Magic Square。

2.1.2 generateMagicSquare()

首先判断输入的生成矩阵大小,若为偶数或负数则返回失败。
生成方法:首先判断参数满足条件后,创建一个 n × n n×n n×n大小二维数组,首先取 n n n的一半,在矩阵第一行中间位置插入1,接下来在底部中间往右插入2,向右上方对角线一次插入3,4…直到碰到右边界。此时col归0,从左侧中间开始以此向右上方对角线继续依此插入,直到i被square整除,于是row - 1,往下一行开始又继续向右上方对角线依此插入知道row又为0,再从右下方开始以此按上述规律继续插入,不断折返直到右下角和中间到左上方被填满,再从中间下方和左上角仍按原规律继续填充直到整个矩阵被填满,至此Magic Square构造完毕。

2.2 Turtle Graphics

Turtle库是Python语言中一个流行的绘制图像的函数库。在计算机图形学中,Turtle图形是使用笛卡尔平面上的相对光标的矢量图形。 Turtle图形是Logo编程语言的一个关键特性。要求用Java来实现Turtle Graphics的部分功能,实现后即可绘制各种复杂绚丽的图形。

2.2.1 Problem 1: Clone and import

从提供的网站中下载代码,并根据规格要求复制粘贴到指定位置,修改相关包引用,并根据要求进一步调整。
创建git:从官网上下载,并根据手册要求,在macOS系统上配置git本地仓库。

2.2.2 Problem 3: Turtle graphics and drawSquare

要求绘制一个正方形。只需简单地利用提供的所给的函数,每次向前后转90度,循环4次即可完成。

2.2.3 Problem 5: Drawing polygons

要求绘制一个正多边形。只需简单地利用提供的所给的函数,求出正n边形的内角,利用内角与边数的互相转化,每次向前后转一定度数,循环n次即可完成。

2.2.4 Problem 6: Calculating Bearings

要求给定一个点的列表,求出这些点依次链接的转向角。首先需要求出转向角,需要根据当前坐标与目标坐标与方向计算出转向角。求转向角最主要的问题在于转向角度必须是0到360度的,且必须是顺时针方向。首先计算出目标的相对位置,便于接下来进一步进行计算。若正好在x或y轴方向上则直接返回,以免不必要的计算。处理完成后进行下一步处理,首先根据反正切算出绝对转向角度,但该角度只能是0到180度,需要根据象限做进一步计算。根据不同象限,将角度限定为顺时针旋转角。最后根据初始角度,用绝对转向角加或减,将最终角度限定到0到360度内。主要困难在于各种情况的判断。
接下来需要计算各个点之间的转向角,由于给定了一个链表,可以便利依此计算。先算出第一组,接下来只需要根据上一个初始角不断计算接下来的转向角即可。

2.2.5 Problem 7: Convex Hulls

要求根据已知点集算出该点集的凸包点列表。首先应该判断集合大小,若小于3个点则直接返回,因为三个及以下的点凸包就是本身。大于3时,将给定的集合转化为数组便于进一步操作。首先根据卷包裹算法,要先给定一个确定在凸包上的点,新建一个数组B用于储存点集,先对转化得到的数组B根据x, y坐标和进行排序(确保防止出现只按x或y排序造成第一个点处于几个点连成的直线中间,最后无法判断出是否时直线顶点上的点情况),选取一个x坐标最小的点,则该点必为一个凸包上的点,标为以遍历。接下来进入循环,先找出一个未遍历过的点,根据在Point类中自定义的一个方法,可以根据三个点求出两个向量的叉积,遍历所有点,根据当前已确定的在凸包上的点,每次循环都选出一个更外侧的点直到最终选择出最外侧的点,如果是共线(叉积为0)则选出距离最远的点。这样经过一次遍历便得到一个新的在凸包上的点,加入凸包点集并标记为已经访问,接下来将last点当作新的凸包点,重新进入循环。最终当最外侧点只能为扫描到的点时说明已经完成凸包的建立。结束算法。主要困难在于选取最外点的向量叉积算法。
测试后发现完全通过。

2.2.6 Problem 8: Personal art

要求根据已完成方法实现DIY图形。可以利用Turtle绘制各种复杂图形,具体实现了几种情况。

2.2.7 Submitting

在Terminal中指定目录下git建立track,并将制定文件stage,并commit。最后git push即可。

2.3 Social Network

本质上是考察图结构的建立与访问。

2.3.1 设计/实现FriendshipGraph

给出你的设计和实现思路/过程/结果。
便于操作,使用了邻接矩阵来储存图。
FriendshipGraph类包含了全部方法,main方法是给出的测试样例;addVertex方法是添加节点的方法,首先判断是否重名,否则不能加入;addEdge则直接将矩阵对应位置转化为true则表示建立了一条新边;考察两个节点的距离,使用了可达矩阵求解,尽管它的复杂度很高,但实现却更加简单,只需计算邻接矩阵的乘法即可,统计在预期的边变为true前相乘的次数即可,若已经相乘n次仍不可达则表示不能相通,返回-1。

2.3.2 设计/实现Person

比较创新性地加入了rank作为每个Person身份的表识,极大地简化了矩阵的建立与计算过程,每实例化一个Person,rank便+1,依此来识别每个人。

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

main方法内容主要是创建对象,其他均为所给的测试样例,不加详述。

2.3.4 设计/实现测试用例

给出你的设计和实现思路/过程/结果。
如上所述,addVertex方法是添加节点的方法,首先判断是否重名,否则不能加入;addEdge则直接将矩阵对应位置转化为true则表示建立了一条新边;考察两个节点的距离,使用了可达矩阵求解,尽管它的时间复杂度很高,但实现却更加简便,在数据量不大时比较方便,只需计算邻接矩阵的乘法即可,统计在预期的边变为true前相乘的次数即可,若已经相乘n次仍不可达则表示不能相通,返回-1。建立邻接矩阵后,运用以上方法即可返回预期值。

2.4 Tweet Tweet

2.4.1 Problem 1: Extracting data from tweets

2.4.1.1 Timespan

只需返回时间段。遍历求出最早时间点和最晚时间点,相减即可。

2.4.1.2 getMentionedUsers

需要根据tweet列表求出提及的author。
主要使用正则表达式进行匹配。在text中寻找符合author的标志@,使用正则表达式"(?:[^\\w]|^)@([\\w](file:///w)+)",并将匹配出的author用group添加到字符串中并使用collect及流,转化为Set

2.4.2 Problem 2: Filtering lists of tweets

2.4.2.1 writtenBy

只需遍历tweet并将与username相等的Author返回即可。

2.4.2.2 inTimespan

只需遍历tweets,选择出timespan中的tweet即可。

2.4.2.3 containing

使用filter过滤器简化操作。选择谓词中使用如下判断。
若没有text或words则不挑选,将text转化为小写以不区分大小写。使用正则表达式"\\b"+ word.toLowerCase() + "\\b"即可挑选推文中的单个符合条件的单词。最后使用流转化为List返回。

2.4.3 Problem 3: Inferring a social network

2.4.3.1 guessFollowsGraph

在getAllUsers方法中选测出全部username(@以及author),并在getMentionedUsersExceptHimself方法中选择出除了author以外所提及的author。
最后将usernamementioned users转为Map即可。

2.4.3.2 influencers

首先需要计算出每个用户的影响力(Rank),只需计算出followsGraph中的values的大小(Follower数量)作为Rank。
建立一个followerSet集合储存所有的follower,在followsGraph2中存入不区分大小写的在followerSet里的username,再将followsGraph2中的key和用户的Rank存入新的Map。将followsGraph2转化为List,最后根据Rank排序即可。

2.4.4 Problem 4: Get smarter

使用了Trend(#Something)作为评判依据。使用与之前相似的方法,在每个text中使用正则表达式提取趋势,并且认为每个趋势下的Author具有相互影响力,使用流和过滤器完成操作。本来想使用lambda表达式返回,但是最后发现参数不匹配,只能用传统循环依次操作。运行过程中发现该步运行稍慢,可能需要几秒左右。
测试全部通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值