软件构造实验一

  1. 实验目标概述

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

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

系统:windows10,JDK8

ide:Eclipse IDE for Eclipse Committers 2018-12 (4.10.0)

版本管理:git

代码托管:Github

        1. 配置过程

按照lab0中指导,进行eclipse与git的安装与配置

在官网下载jdk8并安装与环境变量的配置

在官网下载git并安装,绑定自己的私有仓库,并添加SSH  key这样以合提交时候会方便很多,并设置颜色等等

在创建项过程中由于下载的实验目录与实验要求的不同需要更给包名,最开始没有注意到目录结构

将代码放入是报错出现org.junit不存在需要导入junit包

对git命令的不熟悉,通过搜索教程慢慢学习

 

在这里给出你的GitHub Lab1仓库的URL地址(Lab1-学号)。

https://github.com/ComputerScienceHIT/Lab1-1170300527.git

  1. 实验过程

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

为了条理清晰,可根据需要在各节增加三级标题。

    1. Magic Squares

该问题主要是1.对文件读入判断其的矩阵判断是否为幻方,要求输入的矩阵必须为\t分割且必须为元素必须是整数。2理解其给出的函数并对其添加注释,按要求对其进行扩展并判断据此生成的矩阵是否满足幻方

      1. isLegalMagicSquare()

首先进行文件按行的读入,对其用\t进行分割,因为要求源文件只能用\t隔开,还对其进行了空格的分割,如果空格分割结果长度大于1说明其不满足要求;并记录每行元素个数,没读入一行进行比较。由于读入的是字符串,所以还要用Integer.parseInt()将其转化为int型的数据,按要求数据必须为整数否则返回false,而当输入数据格式不满足int型时Interger.paseInt会产生异常,故用try catch进行异常的捕获并返回false;当数据全部读入后比较行列数是否相等判断其是否满足矩阵;如果上述条件都满足则进行行、列、对角线和的判断是否相等,相等则返回true,不相等则返回false

 

实验结果:

1.txt: true

2.txt: true

3.txt: 不是矩阵   false

4.txt: 数据存在非整数 false

5.txt: 存在不是"\t"分割的数据 false

      1. generateMagicSquare()

magic square生成方法:

  1. 首先向第一行正中的方格内填写1
    2.  以下依次向右上角的方格内填写2、3、4……
        1.  若右上角的方格内已经有数字,则向下移动一格继续填写
        2.  若右上角的方格超出矩阵的行,则移到矩阵下一列的最下端继续填写
        3.  若右上角的方格超出矩阵的列,则移到矩阵下一行的最左端继续填写

代码中对于2.1判断是通过判断输入的元素数量是否是行的倍数来实现的效果也是相同的

当输入偶数时由于最初始的位置并不是第一行中间随后会发生数组越界,而输入负数时由于数组并[]内使用负数时也会产生异常

结果:

  1. 正常结果(n为5)

17  24  1   8   15 

23  5   7   14  16 

4   6   13  20  22 

10  12  19  21  3  

11  18  25  2   9  

true

  1. 输入偶数(6):

输入偶数 false

  1. 输入负数(-5)

输入负数 false

    1. Turtle Graphics

本问要实现的是海归画图,前几个小问比较简单,较难的在于Problem 6对各种情况的分类处理以及Problem 7的凸包问题的分析

      1. Problem 1: Clone and import

如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。

      1. Problem 3: Turtle graphics and drawSquare

要求只是画一个正方形,for循环四次每次转90度即可

      1. Problem 5: Drawing polygons

需要实现两个方法:calculateRegularPolygonAngle()和drawRegularPolygon()方法,并使用Junit测试。

calculateRegularPolygonAngle()方法要求根据给定的边数作为参数,计算出对应的正多边形的内角。只需要使用公式(sides - 2) * 180 / sides即可注意要转化为double类型。

drawRegularPolygon()方法根据输入的长度和边数画出正多边形,首先调用calculateRegularPolygonAngle()得到角度,得到的是内角而海龟转的是外角要先进行转换,之后通过循环即可画出。

      1. Problem 6: Calculating Bearings

需要实现两个方法:calculateBearingToPoint()和calculateBearings()方法,并进行Junit测试。

calculateBearingToPoint()选取的是先算出若初始角度为0时需要转的度数,并与真正的初始角度比较大小判断位置计算出真正要转的角度,本问的主要难点在于要进行的是对各种不同情况的讨论:

  1. 当两点的x坐标相同时:比较y的大小判断点的位置并计算角度
  2. 1.用 Math.atan2() * 180 / Math.PI计算两点的相对角度,如果是负数则加上360度

2.将相对角度与初始的角度对比,计算需要转过的角度

calculateBearings()方法传入的时两个list分别是x,y值,只需调用calculateBearingToPoint()方法即可,但要注意要时刻记录当前角度而不是转过的角度

      1. Problem 7: Convex Hulls

凸包问题也是本题的难点,根据给出的提示使用礼物包装算法,从左上角开始找出转最小角度到达的下一个点,如果多个点角度相同则找距离最远的点,最终找到初始点结束。首先对之前的求偏转角度的函数进行重写doubleToPoint()方法使其传入参数为double类型,并且在输入两个点相同时返回360度否则自己找到自己时为0度会陷入死循环。找到左上点作为初始点,之后扫描所有点并记录当前角度,需转角度,当前两点间长度找出最合适的点作为下一点,不断循环直到找到初始点。

      1. Problem 8: Personal art

本问比较开心可以自由发挥画出一些有趣的图形,只需画一个基础的图形不断循环即可得到一个有规律较好看的图形也可随意画出自己想要的图形

      1. Submitting

如何通过Git提交当前版本到GitHub上你的Lab1仓库。

    1. Social Network

完成Person和FriendshipGraph类,建立一个社交网络,并能计算两个人之间的距离

      1. 设计/实现FriendshipGraph类

由于人数是未知的,故vertex采用ArrayList类型,表示人的关系的edge使用邻接表进行行创建并使用ArrayList<ArrayList>。

addVertex:每添加一个people时要检验是否已经存在这个人使用重写的equals方法比较是否已经存在如存在则抛出异常,否则在每一个arraylist最后添加0并添加一行,注意arrraylist中添加的值指针,故每次添加一行时要重新new一个arraylist;

addEdge:添加两个人之间的关系时通过getIndex方法得到两个人的下标,并将edge中的点设为1

getDistance:立用广度优先搜索,遍历到该点时的层次极为距离,若由队列空才退出则说明两点之间不存在关系返回-1,

      1. 设计/实现Person类

只有一个name属性,并重写equal方法比较姓名是否相同

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

即实验中的示例代码

结果:  1

              2

              0

              -1

      1. 设计/实现测试用例

即实验示例中的添加的元素与边,每添加一个人和一个边时都对实际结果与预期结果进行比较判断是否相同

    1. Tweet Tweet

该试验对一些Twitter进行基础的分析,通过特征分析,猜测出各个用户之间的关注关系,并分析出“最受欢迎”的人。

      1. Problem 1: Extracting data from tweets

要求实现两个方法:getTimespan()和getMentionedUsers()并进行相应的测试。

getTimespan():传入的是一个tweet的list组,要求找到其中最小的时间跨度,Instant替代Data的一个类包含isBefore()和isAfter()方法比较时间的先后,只需要对tweets进行遍历即可得到最早时间和最晚时间

getMentionedUsers():要求找出@的人,按照给出的username的定义构造正则表达式使用零宽断言"(?<![A-Za-z0-9_-])@[A-Za-z0-9_-]{1,140}(?![A-Za-z0-9_-])"遍历tweet匹配正则表达式将符合条件的加入set中

      1. Problem 2: Filtering lists of tweets

对tweets进行按要求过滤。要求实现writtenBy()、inTimespan()和containing()方法。

writtenBy():找到相应作者写的tweet,只需对tweet进行遍历,并立用getAuthor方法比较作者即可

inTimespan():找到在相应时间内创建的tweet,立用Timespan的getStart和getEnd得到start和end,并将tweet进行遍历比较创建时间是否在start与end之间

containing():找到包含特定单词的tweet且不区分大小写,建立新的word的list和tweets的list将其中的单词与text全部换为小写但位置不变,构造零宽断言的正则表达式,与上一问中的类似"(?<![A-Za-z0-9_-])" + word+ "(?![A-Za-z0-9_-])"之后对字tweet进行遍历匹配即可

      1. Problem 3: Inferring a social network

要实现对tweet的分析,@了谁并对被@的次数进行排序,@次数越多则影响力越高,完成guessFollowsGraph()和influencers()方法

guessFollowsGraph():返回

  1. 实验目标概述

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

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

系统:windows10,JDK8

ide:Eclipse IDE for Eclipse Committers 2018-12 (4.10.0)

版本管理:git

代码托管:Github

        1. 配置过程

按照lab0中指导,进行eclipse与git的安装与配置

在官网下载jdk8并安装与环境变量的配置

在官网下载git并安装,绑定自己的私有仓库,并添加SSH  key这样以合提交时候会方便很多,并设置颜色等等

在创建项过程中由于下载的实验目录与实验要求的不同需要更给包名,最开始没有注意到目录结构

将代码放入是报错出现org.junit不存在需要导入junit包

对git命令的不熟悉,通过搜索教程慢慢学习

 

在这里给出你的GitHub Lab1仓库的URL地址(Lab1-学号)。

https://github.com/ComputerScienceHIT/Lab1-1170300527.git

  1. 实验过程

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

为了条理清晰,可根据需要在各节增加三级标题。

    1. Magic Squares

该问题主要是1.对文件读入判断其的矩阵判断是否为幻方,要求输入的矩阵必须为\t分割且必须为元素必须是整数。2理解其给出的函数并对其添加注释,按要求对其进行扩展并判断据此生成的矩阵是否满足幻方

      1. isLegalMagicSquare()

首先进行文件按行的读入,对其用\t进行分割,因为要求源文件只能用\t隔开,还对其进行了空格的分割,如果空格分割结果长度大于1说明其不满足要求;并记录每行元素个数,没读入一行进行比较。由于读入的是字符串,所以还要用Integer.parseInt()将其转化为int型的数据,按要求数据必须为整数否则返回false,而当输入数据格式不满足int型时Interger.paseInt会产生异常,故用try catch进行异常的捕获并返回false;当数据全部读入后比较行列数是否相等判断其是否满足矩阵;如果上述条件都满足则进行行、列、对角线和的判断是否相等,相等则返回true,不相等则返回false

 

实验结果:

1.txt: true

2.txt: true

3.txt: 不是矩阵   false

4.txt: 数据存在非整数 false

5.txt: 存在不是"\t"分割的数据 false

      1. generateMagicSquare()

magic square生成方法:

  1. 首先向第一行正中的方格内填写1
    2.  以下依次向右上角的方格内填写2、3、4……
        1.  若右上角的方格内已经有数字,则向下移动一格继续填写
        2.  若右上角的方格超出矩阵的行,则移到矩阵下一列的最下端继续填写
        3.  若右上角的方格超出矩阵的列,则移到矩阵下一行的最左端继续填写

代码中对于2.1判断是通过判断输入的元素数量是否是行的倍数来实现的效果也是相同的

当输入偶数时由于最初始的位置并不是第一行中间随后会发生数组越界,而输入负数时由于数组并[]内使用负数时也会产生异常

结果:

  1. 正常结果(n为5)

17  24  1   8   15 

23  5   7   14  16 

4   6   13  20  22 

10  12  19  21  3  

11  18  25  2   9  

true

  1. 输入偶数(6):

输入偶数 false

  1. 输入负数(-5)

输入负数 false

    1. Turtle Graphics

本问要实现的是海归画图,前几个小问比较简单,较难的在于Problem 6对各种情况的分类处理以及Problem 7的凸包问题的分析

      1. Problem 1: Clone and import

如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。

      1. Problem 3: Turtle graphics and drawSquare

要求只是画一个正方形,for循环四次每次转90度即可

      1. Problem 5: Drawing polygons

需要实现两个方法:calculateRegularPolygonAngle()和drawRegularPolygon()方法,并使用Junit测试。

calculateRegularPolygonAngle()方法要求根据给定的边数作为参数,计算出对应的正多边形的内角。只需要使用公式(sides - 2) * 180 / sides即可注意要转化为double类型。

drawRegularPolygon()方法根据输入的长度和边数画出正多边形,首先调用calculateRegularPolygonAngle()得到角度,得到的是内角而海龟转的是外角要先进行转换,之后通过循环即可画出。

      1. Problem 6: Calculating Bearings

需要实现两个方法:calculateBearingToPoint()和calculateBearings()方法,并进行Junit测试。

calculateBearingToPoint()选取的是先算出若初始角度为0时需要转的度数,并与真正的初始角度比较大小判断位置计算出真正要转的角度,本问的主要难点在于要进行的是对各种不同情况的讨论:

  1. 当两点的x坐标相同时:比较y的大小判断点的位置并计算角度
  2. 1.用 Math.atan2() * 180 / Math.PI计算两点的相对角度,如果是负数则加上360度

2.将相对角度与初始的角度对比,计算需要转过的角度

calculateBearings()方法传入的时两个list分别是x,y值,只需调用calculateBearingToPoint()方法即可,但要注意要时刻记录当前角度而不是转过的角度

      1. Problem 7: Convex Hulls

凸包问题也是本题的难点,根据给出的提示使用礼物包装算法,从左上角开始找出转最小角度到达的下一个点,如果多个点角度相同则找距离最远的点,最终找到初始点结束。首先对之前的求偏转角度的函数进行重写doubleToPoint()方法使其传入参数为double类型,并且在输入两个点相同时返回360度否则自己找到自己时为0度会陷入死循环。找到左上点作为初始点,之后扫描所有点并记录当前角度,需转角度,当前两点间长度找出最合适的点作为下一点,不断循环直到找到初始点。

      1. Problem 8: Personal art

本问比较开心可以自由发挥画出一些有趣的图形,只需画一个基础的图形不断循环即可得到一个有规律较好看的图形也可随意画出自己想要的图形

      1. Submitting

如何通过Git提交当前版本到GitHub上你的Lab1仓库。

    1. Social Network

完成Person和FriendshipGraph类,建立一个社交网络,并能计算两个人之间的距离

      1. 设计/实现FriendshipGraph类

由于人数是未知的,故vertex采用ArrayList类型,表示人的关系的edge使用邻接表进行行创建并使用ArrayList<ArrayList>。

addVertex:每添加一个people时要检验是否已经存在这个人使用重写的equals方法比较是否已经存在如存在则抛出异常,否则在每一个arraylist最后添加0并添加一行,注意arrraylist中添加的值指针,故每次添加一行时要重新new一个arraylist;

addEdge:添加两个人之间的关系时通过getIndex方法得到两个人的下标,并将edge中的点设为1

getDistance:立用广度优先搜索,遍历到该点时的层次极为距离,若由队列空才退出则说明两点之间不存在关系返回-1,

      1. 设计/实现Person类

只有一个name属性,并重写equal方法比较姓名是否相同

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

即实验中的示例代码

结果:  1

              2

              0

              -1

      1. 设计/实现测试用例

即实验示例中的添加的元素与边,每添加一个人和一个边时都对实际结果与预期结果进行比较判断是否相同

    1. Tweet Tweet

该试验对一些Twitter进行基础的分析,通过特征分析,猜测出各个用户之间的关注关系,并分析出“最受欢迎”的人。

      1. Problem 1: Extracting data from tweets

要求实现两个方法:getTimespan()和getMentionedUsers()并进行相应的测试。

getTimespan():传入的是一个tweet的list组,要求找到其中最小的时间跨度,Instant替代Data的一个类包含isBefore()和isAfter()方法比较时间的先后,只需要对tweets进行遍历即可得到最早时间和最晚时间

getMentionedUsers():要求找出@的人,按照给出的username的定义构造正则表达式使用零宽断言"(?<![A-Za-z0-9_-])@[A-Za-z0-9_-]{1,140}(?![A-Za-z0-9_-])"遍历tweet匹配正则表达式将符合条件的加入set中

      1. Problem 2: Filtering lists of tweets

对tweets进行按要求过滤。要求实现writtenBy()、inTimespan()和containing()方法。

writtenBy():找到相应作者写的tweet,只需对tweet进行遍历,并立用getAuthor方法比较作者即可

inTimespan():找到在相应时间内创建的tweet,立用Timespan的getStart和getEnd得到start和end,并将tweet进行遍历比较创建时间是否在start与end之间

containing():找到包含特定单词的tweet且不区分大小写,建立新的word的list和tweets的list将其中的单词与text全部换为小写但位置不变,构造零宽断言的正则表达式,与上一问中的类似"(?<![A-Za-z0-9_-])" + word+ "(?![A-Za-z0-9_-])"之后对字tweet进行遍历匹配即可

      1. Problem 3: Inferring a social network

要实现对tweet的分析,@了谁并对被@的次数进行排序,@次数越多则影响力越高,完成guessFollowsGraph()和influencers()方法

guessFollowsGraph():返回每个人都@了谁的map,key为username,value为@人的set集合,首先建立所有用户的set遍历tweets得到所有用户,对该set遍历对其中每一个username使用writtenBY方法得到其发表的tweets,再调用getMentionedUsers得到其@的用户,然后put进map即可

influencers()方法:返回一个list其中为username按被@次数的影响力排序的,要求要对map中@的人是否有@都要处理,所以重建了一个map并将@删掉;之后建立一个key为username,value为被@次数的map,然后对followsGraph其中的value进行遍历,将其中的username作为key得到map的value将其加1并重新put进行,之后使用Collections.sort接口对该Map进行排序,使用匿名内部类实现Comparator接口按value的大小排序,将其中的key按顺序存入list中即可

      1. Problem 4: Get smarter

MyGuessFollowsGraph更聪明,增加了topic的判断,当多个人提到同一个topic时认为他们互相@,立用正则表达式搜索所有topic,建立tagMapkey值为topic,value为带有该话题的tweet用户,建立关系时首先和guessFollowsGraph()基本相同得到初始的map,然后对tagMap进行遍历,使其中set中的username的互相关注即可

每个人都@了谁的map,key为username,value为@人的set集合,首先建立所有用户的set遍历tweets得到所有用户,对该set遍历对其中每一个username使用writtenBY方法得到其发表的tweets,再调用getMentionedUsers得到其@的用户,然后put进map即可

influencers()方法:返回一个list其中为username按被@次数的影响力排序的,要求要对map中@的人是否有@都要处理,所以重建了一个map并将@删掉;之后建立一个key为username,value为被@次数的map,然后对followsGraph其中的value进行遍历,将其中的username作为key得到map的value将其加1并重新put进行,之后使用Collections.sort接口对该Map进行排序,使用匿名内部类实现Comparator接口按value的大小排序,将其中的key按顺序存入list中即可

      1. Problem 4: Get smarter

MyGuessFollowsGraph更聪明,增加了topic的判断,当多个人提到同一个topic时认为他们互相@,立用正则表达式搜索所有topic,建立tagMapkey值为topic,value为带有该话题的tweet用户,建立关系时首先和guessFollowsGraph()基本相同得到初始的map,然后对tagMap进行遍历,使其中set中的username的互相关注即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值