LAB1

 

1 实验目标概述... 1

2 实验环境配置... 1

3 实验过程... 1

3.1 Magic Squares. 2

3.1.1 isLegalMagicSquare().. 2

3.1.2 generateMagicSquare() 3

3.2 Turtle Graphics. 5

3.2.1 Problem 1: Clone and import 5

3.2.2 Problem 3: Turtle graphics and drawSquare. 5

3.2.3 Problem 5: Drawing polygons. 5

3.2.4 Problem 6: Calculating Bearings. 5

3.2.5 Problem 7: Convex Hulls. 5

3.2.6 Problem 8: Personal art 6

3.2.7 Submitting. 6

3.3 Social Network. 6

3.3.1 设计/实现FriendshipGraph类... 6

3.3.2 设计/实现Person类... 7

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

3.3.4 设计/实现测试用例... 8

3.4 Tweet Tweet 10

3.4.1 Problem 1: Extracting data from tweets. 10

3.4.2 Problem 2: Filtering lists of tweets. 10

3.4.3 Problem 3: Inferring a social network. 10

3.4.4 Problem 4: Get smarter 10

4 实验进度记录... 10

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

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

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

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

 

 

 

1 实验目标概述

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

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

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

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

基本的 Java OO 编程;

基于 Eclipse IDE 进行 Java 编程;

基于 JUnit 的测试;

基于 Git 的代码配置管理。

2 实验环境配置

简要陈述你配置本次实验所需开发、测试、运行环境的过程,必要时可以给出屏幕截图。

特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

  1. 用eclipse在本地新建一个项目;
  2. 在命令行中用“git init”新建库
  3. 利用git remote add origin <url>将本地库和远程库链接
  4. 将远程源中master分支的仓库拉到本地git push -u origin maste
  5. Git add .打包本地项目
  6. Git commit -m “20190301”为本地文件做标记
  7. Git push origin master推送上仓库

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

https://github.com/ComputerScienceHIT/Lab1-1170400307

3 实验过程

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

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

3.1 Magic Squares

问题理解:本问题要求实现判断一个nxn矩阵是否是一个幻方,并且理解一个针对n为奇数的幻方的生成算法。主要考察点:Java基本语法,文件读写,判断输入的合法性。

3.1.1 isLegalMagicSquare()

 

1.    读入文本。

InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("src/P1/txt/" + fileName)),"UTF-8");

              BufferedReader stream = new BufferedReader(reader);

2检查有没有非法字符,对于本题来说,合法的字符只有’0’到’9’和’\t’。

 if(test[i].contains(".") || test[i].contains("-"))

                            {

                            System.out.print("contais - or .");

                            return false;

                            }

3检查是不是方阵。检查每一行的字符数是否等于行数。

if(checkStrings.length!=row)

                            {

                            System.out.print("lines is not equal rows");

                            return false;

                            }

4以上条件都满足时再判断是不是幻方。

          for (int i = 0; i < row; i++) {

                     sum[i]=0;

                     checkStrings=test[i].split("\t");

                     if(checkStrings.length!=row)

                            {

                            System.out.print("lines is not equal rows");

                            return false;

                            }

                     for (int j = 0; j < checkStrings.length; j++) {

                            result[i][j]=Integer.valueOf(checkStrings[j]);

                     }

                     for (int j = 0; j < row; j++) {

                            sum[i]=sum[i]+result[i][j];

                     }

              }

              for (int i = 0; i < row; i++) {

                     sum[i+row]=0;

                     for (int j = 0; j < row; j++) {

                            sum[i+row]=sum[i+row]+result[j][i];

                     }

              }

              sum[2*row]=0;

              sum[2*row+1]=0;

              for(int i=0;i<row;i++)

              {

                     sum[2*row]=sum[2*row]+result[i][i];

                     sum[2*row+1]=sum[2*row+1]+result[i][row-1-i];

              }

              for (int i = 1; i <= 2*row+1; i++) {

                     if(sum[i-1]!=sum[i])

                            {

                            System.out.print("sums are not equal");

                            return false;

                            }

3.1.2 generateMagicSquare()

思路:使用罗伯法构造一个n为奇数的nxn幻方。罗伯法的算法为把1(或最小的数)放在第一行正中;按以下规律排列剩下的(n×n-1)个数:

(1)每一个数放在前一个数的右上一格;

(2)如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;

(3)如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;

(4)如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在底行且最左列;

(5)如果这个数所要放的格已经有数填入,那么就把它放在前一个数的下一行同一列的格内。

 

3.2 Turtle Graphics

该任务需要我去自主学习java的一个第三方画图方案Turtle,并且通过给出的现有的Turtle方法实现题目要求的画图任务,并且借助数学工具进行解题。

3.2.1 Problem 1: Clone and import

利用get clone命令行

3.2.2 Problem 3: Turtle graphics and drawSquare

这个函数的功能是画一个正方形。需要调用两个方法foward(int units)向当前方向画直线,长度是输入的数字,单位是内部规定单位。turn(double degrees)按照顺时针方向旋转画图方向。

3.2.3 Problem 5: Drawing polygons

这个任务包含几个小任务。

(1)calculateRegularPolygonAngle 计算正多边形的内角,(边数-2)/sides。

(2)int calculatePolygonSidesFromAngle(double angle)

这个方法和上一个类似,根据角度计算正多边形边数。

(3)drawRegularPolygon :调用calculateRegularPolygonAngle(sides)计算正多边形的内角为rotation,调用turtle.forward和turtle.turn进行前进和转向。

3.2.4 Problem 6: Calculating Bearings

calculateBearingToPoint :计算(当前点,当前朝向)构成的向量与(当前点,目标点)构成的向量之间的夹角,首先计算(当前点,目标点)构成的向量与y轴之间的tan,使用Math.atan2计算与y轴夹角,与当前朝向夹角(与y轴之间)作差计算两向量之间的夹角,需要注意负角变正角。

calculateBearings:对列表中的每两个相邻节点调用calculateBearingToPoint计算夹角。

3.2.5 Problem 7: Convex Hulls

这个是运用凸包算法。即对于一组输入的平面点集,求一个最小的集合组成的凸包,使这个凸包的所有点组成的凸多边形可以围着所有的点。

我采取的是gift-wrapping算法,这个算法形象的理解是,先选取一个必定在凸包里的点作为起点,这个点可以选取纵坐标最小的点(当存在多个纵坐标最小的点时,选取其中横坐标最小的点)。然后想象用一根绳子从起点出发,把平面上的所有点紧紧的围在一起,这条绳子上的拐点就是凸包上的点。

我的设计值得注意的几点是

1将输入的存放点集的set改成数组,方便操作

2通过向量叉积判断向量方位,例如A*B当A需要逆时针才能转向B时,A*B的值是正的。

3.2.6 Problem 8: Personal art

利用如下指令,借助函数改变绘画形状和颜色:

public static void drawPersonalArt(Turtle turtle) {

        for (int i = 0 ; i < 1500; i++) {

            turtle.forward(i/2);

            switch ((i/15) % 10) {

                case 0:turtle.color(PenColor.BLACK);break;

                case 1:turtle.color(PenColor.GRAY);break;

                case 2:turtle.color(PenColor.RED);break;

                case 3:turtle.color(PenColor.PINK);break;

                case 4:turtle.color(PenColor.ORANGE);break;

                case 5:turtle.color(PenColor.YELLOW);break;

                case 6:turtle.color(PenColor.GREEN);break;

                case 7:turtle.color(PenColor.CYAN);break;

                case 8:turtle.color(PenColor.BLUE);break;

                case 9:turtle.color(PenColor.MAGENTA);break;

            }

            turtle.turn(91);

        }

       }

3.2.7 Submitting

利用git push命令行

3.3 Social Network

该任务是需要我去建立一个图,通过输入搭建有向社交网,并且给出正确的输出,对非法输入进行正确的判断。

3.3.1 设计/实现FriendshipGraph类

我采用的是邻接表的展示结构,效率较高。在List类型内装入Person类型,而且每一个Person内有List存储每一个人的序号

对于求出两个person之间的距离,先调用方法 calculateDistance

       private void calculateDistance(Person name1){

           int size = name1.getIdSize();

           List<Integer> id = name1.getId();

           for(int i = 0; i < size; i ++){

               Person person = nameList.get(id.get(i));

               if(!person.getKnown()){

                   person.setDistance(name1.getDistance()+1);

                   person.setKnown(true);

                   calculateDistance(person);

               }else{

                   if(name1.getDistance()+1<person.getDistance()){

                    person.setDistance(name1.getDistance()+1);

                   }

               }

           }

       }

这个方法以一个person为起点进行深度优先搜索,标记搜索过的点,并记录距起始搜索点的距离,然后通过getDistance方法获得两个person之间的信息,如果另一个person的distance是0,说明是同一个点,如果未搜索到,说明无关系,返回-1。

3.3.2 设计/实现Person类

Person设计尽量满足以下几点

1成员变量设置成private,成员变量的访问是通过成员方法进行的

2满足FreindshipGraph的要求

以下是源代码

public class Person{

    private String name;

    private boolean known;

    private int distance;

    private List<Integer> id = new ArrayList<>();

    public boolean getKnown(){

        return known;

    }

    public int getDistance(){

        return distance;

    }

    public void setDistance(int Distance){

        this.distance = Distance;

    }

    public String getName() {

        return name;

    }

    public void setKnown(boolean flag){

        known = flag;

    }

    public List<Integer> getId(){

        return id;

    }

 

    public int getIdSize(){

        return id.size();

    }

    public boolean existId(int id){

        if(this.id.contains(id)){

            return true;

        }

        return false;

    }

    public void setId(int p) {

           Integer P = new Integer(p);

           this.id.add(P);

    }

    public Person(String name){

        this.name = name;

    }

}

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

客户端代码实验文档已经提供

          FriendshipGraph graph = new FriendshipGraph();

          Person rachel = new Person("rachel");

          Person ross = new Person("ross");

          Person ben = new Person("ben");

          Person kramer = new Person("kramer");

          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));

          System.out.println(graph.getDistance(rachel,ben));

          System.out.println(graph.getDistance(rachel,rachel));

          System.out.println(graph.getDistance(rachel,kramer));

3.3.4 设计/实现测试用例

主要对计算距离的算法进行了测试。

public void GetDistanceTest() {

              FriendshipGraph graph = new FriendshipGraph();

              Person rachel = new Person("Rachel");

              Person ross = new Person("Ross");

              Person ben = new Person("Ben");

              Person kramer = new Person("Kramer");

              Person abc = new Person("abc");

              Person def = new Person("def");

              Person hij = new Person("hij");

              Person lmn = new Person("lmn");

              graph.addVertex(rachel);

              graph.addVertex(ross);

              graph.addVertex(ben);

              graph.addVertex(kramer);

              graph.addVertex(abc);

              graph.addVertex(def);

              graph.addVertex(hij);

              graph.addVertex(lmn);

              graph.addEdge(rachel, ross);

              graph.addEdge(ross, rachel);

              graph.addEdge(ross, ben);

              graph.addEdge(ben, ross);

              graph.addEdge(rachel, def);

              graph.addEdge(def, rachel);

              graph.addEdge(abc, ross);

              graph.addEdge(ross, abc);

              graph.addEdge(hij, ross);

              graph.addEdge(ross, hij);

              graph.addEdge(lmn, ben);

              graph.addEdge(ben, lmn);

              assertEquals(1, graph.getDistance(rachel, ross));

              assertEquals(2, graph.getDistance(rachel, ben));

              assertEquals(0, graph.getDistance(rachel, rachel));

              assertEquals(-1, graph.getDistance(rachel, kramer));

              assertEquals(2, graph.getDistance(rachel, abc));

              assertEquals(1, graph.getDistance(rachel, def));

              assertEquals(2, graph.getDistance(rachel, hij));

              assertEquals(3, graph.getDistance(rachel, lmn));

       }

3.4 Tweet Tweet

3.4.1 Problem 1: Extracting data from tweets

getTimespan:

如果tweets为空则将当前时间作为始末时间点构造Timespan,否则调用getEarliestTime和getLatestTime分别获得所有tweets中的最早发表时间和最晚发表时间构造Timespan。时间比较调用Time.isBefore和Time.isAfter函数。

getMentionedUsers

检测tweet的text部分,先找到字符@,然后检测@前一个字符,当不是有效字符时,记录@后面的有效字符,即是我们要找的字符串。

3.4.2 Problem 2: Filtering lists of tweets

writtenBy:for循环检查所有tweet,获取username,然后和我们的字符串比较,相等即匹配成功。

inTimespan:利用Time.isBefore和Time.isAfter进行比较。

containing:先利用toLowerCase函数把推文内容和待查找字符串都转化为小写字母形式,然后直接调用contains函数进行检查。

3.4.3 Problem 3: Inferring a social network

guessFollowGraph:第一种证据思路是如果一名author在tweet中@过其他人,那么该author就会follow这些被@的人。扫描每条tweet,调用Extract.getMentionedUsers提取出该条tweet中所有被@到的人,将这些人加入到Map[author]->Set<Stirng>中。

public static List<String> influencers(Map<String, Set<String>> followsGraph)

influencers:按照社交网络的影响力(follow数目)对所有user进行排名。首先根据followsGraph统计每个人的follow数目,再对每个人的follow数目进行排名。

3.4.4 Problem 4: Get smarter

我采用的是最简单的寻找推文中的话题,利用话题的集合程度来表达两个人之间关系的亲密。

算法上和之间的寻找@的人物十分类似,我们的主要目的是希望找到两个具有相同话题的人,如果在此基础之上,两个人又有互相@的行为,我们就可以判定为他们的关系不应该局限于“互相影响上面”,而有可能是其他关系,例如朋友。

4 实验进度记录

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

日期

时间段

任务

实际完成情况

2019-3-1

15:45-17:30

配置好实验环境和编译器

按计划完成

2019-3-5

15:45-17:30

完成项目1

延期1小时完成

2019-3-7

15:45-17:30

完成项目2

遇到困难,未完成

2019-3-10

15:45-17:30

完成项目3

提前一小时完成

2019-3-15

15:45-17:30

完成项目4

遇到困难,求助谷歌

2019-3-17

15:45-17:30

完成实验报告

按计划完成

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

遇到的难点

解决途径

对git使用不清楚

 

 

仔细阅读《git中文使用手册》

对于JAVA基本语法不熟悉

 

 

仔细学习《JAVA编程思想》

题目有点难度,错误比较多

 

 

逐次调试,改正bug

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

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

1.关于JAVA的一些基础知识不会,网上也没有适合的资料,学习的过程浪费了一些时间。

2.题目是英文的,阅读起来有些难度,需要借助于网络工具,很多时候对题意的理解也有问题,很难下手。

3.自己的代码写的很差,没有章法,没有明确的思路,结构也很混乱,只能保证答案正确。

6.2 针对以下方面的感受

(1)   Java编程语言是否对你的口味?

JAVA是世界上最好的编程语言。

(2)   关于Eclipse IDE

Eclipse是世界上最好的IDE。

(3)   关于Git和GitHub

Git和GitHub是世界上最好的代码交流项目。

(4)   关于CMU和MIT的作业

作业很难,做作业的过程很艰辛,通过做CMU和MIT的作业,我深刻地认识到了自己和它们学生之间的差距,怪不得我考不上CMU和MIT。

(5)   关于本实验的工作量、难度、deadline

做完之后感觉难度还是有点大的,主要原因在于自己第一次用JAVA,关于语法和算法的基础知识属于现学现用,,只能照葫芦画瓢,很艰难。

(6)   关于初接触“软件构造”课程

上课的内容和实验的内容有一定差距,很多实验内容要自学,目前基础太差,以后需要更加努力。

转载于:https://www.cnblogs.com/richardodliu/p/10929515.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值