软件构造实验一

 

2020年春季学期
计算机学院《软件构造》课程

 

 

 

 

Lab 1实验报告
 

 

 

 

 

 

 

 

 

姓名

 

 

 

 

目录

 

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

4 实验进度记录... 3

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

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

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

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

 

 

  1. 实验目标概述

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

⚫ 基本的 Java OO 编程

⚫ 基于 Eclipse IDE 进行 Java 编程

⚫ 基于 JUnit 的测试

⚫ 基于 Git 的代码配置管理

  1. 实验环境配置

到网站上下载安装包,由于国内网络的限制,下载非常缓慢。

下载了jdk eclipse git

搭建梯子有所改善。

Junit 4是新版eclipse自带,需要配置java的环境变量

Eclipse可以汉化,但是汉化比例较低。

创建了github账号,发现GitHub访问速度慢,通过改变system32下host文件,直接连接到ip

 

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

 

  1. 实验过程

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

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

    1. Magic Squares

由文本输入幻方,幻方定义是首先为方形,其次行列,对角线之和均相等,

设计文件输入输出,同时需要补充调用generateMagicSquare函数,生成6.txt,并且检验是否为幻方,其中涉及到关于各种异常输入的处理,以及程序中的运行异常的处理。

      1. isLegalMagicSquare()

根据指令读取对应的文件,将其转化存储到数组中,便利一遍数组,根据坐标,将值加和到新创建的加和数组,最后判断加和数组中是否都相等。

              switch (fileName) {// 选取不同的文件作为输入流

              case "1":

                     br1 = new BufferedReader(new FileReader("src\\P1\\txt\\1.txt"));

                     break; // 可选

              case "2":

                     br1 = new BufferedReader(new FileReader("src\\P1\\txt\\2.txt"));

                     break; // 可选

              case "3":

                     br1 = new BufferedReader(new FileReader("src\\P1\\txt\\3.txt"));

                     break; // 可选

              case "4":

                     br1 = new BufferedReader(new FileReader("src\\P1\\txt\\4.txt"));

                     break; // 可选

              case "5":

                     br1 = new BufferedReader(new FileReader("src\\P1\\txt\\5.txt"));

                     break; // 可选

              case "6":

                     br1 = new BufferedReader(new FileReader("src\\P1\\txt\\6.txt"));

                     break; // 可选

              default: // 可选

                     break;

              }

这里使用switch

其实可以用“+”来组合文件名字符串这样可以减少代码量。

             

 

 

 

 

 

double l_to_r = 0, r_to_l = 0;

              double[] hang = new double[edge];

              double[] lie = new double[edge];

              for (i = 0; i < edge; i++) {// 创建两个数组代表每行每列之和 扫描分组属于列或者行或者斜线

                     for (j = 0; j < edge; j++) {

                            hang[i] = hang[i] + num[i][j];

                            lie[j] = lie[j] + num[i][j];

                            if (i == j) {

                                   l_to_r = l_to_r + num[i][j];

                            }

                            if (i + j == edge - 1) {

                                   r_to_l = r_to_l + num[i][j];

                            }

                     }

              }

空间换时间,扫描一遍得到加和数组

      1. generateMagicSquare()

劳伯法生成奇数阶幻方

把1(或最小的数)放在第一行正中;

每一个数放在前一个数的右上一格;若该数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;若该数数所要放的格已经超出了最右列那么就把它放在最左列,上一行;若该数所要放的格已经超出了顶行且超出了最右列,则放在底行左列;若该数所要放的格已经有数填入,那么就把它放在前一个数的下一行同一列的格内

      

try {

                     File file = new File("src\\P1\\txt\\6.txt");

                     if(!file.exists()){

                            file.createNewFile();

                     }

                     FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());

                     BufferedWriter bw = new BufferedWriter(fileWriter);

                     for (i = 0; i < n; i++) {

                            for (j = 0; j < n; j++) {

                                          bw.write(Integer.toString(magic[i][j]));

                                          if (j!=n-1)

                                          bw.write("\t");

                                          // 有try-with-resources或者 close()关闭文件,否则数据就不能正常地保存

                            }

                            bw.write("\n");

                     }

                    

                     bw.close();

                     System.out.println("finish");

           } catch (IOException e) {

               e.printStackTrace();

           }

在原来的基础上加上文件操作,把输出移动到文件。同时增加异常处理中断,当输入是偶数或者不符合规定合理的输出。

    1. Turtle Graphics

首先需要获取源代码,然后创建和管理本地仓库。画正方形、据内角求边数、据边数求内角,画正多边形,计算方位,计算凸包,个性创作。

      1. Problem 1: Clone and import

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

Git Clone 网址到文件夹

 

编写完成以后

Git add .

Git commit -m”备注”

Git push -u origin master

Push到github

      1. Problem 3: Turtle graphics and drawSquare

              turtle.forward(60);

              turtle.turn(90);

              turtle.forward(60);

              turtle.turn(90);

              turtle.forward(60);

              turtle.turn(90);

              turtle.forward(60);

              turtle.draw();

 

 

      1. Problem 5: Drawing polygons

利用多边形相关公式

return (double) (sides - 2) * 180 / (double) sides;

return (int) Math.round(360.0 / (180.0 - angle));

 

由边算角由角算边

      1. Problem 6: Calculating Bearings

       1.    double degree = Math.toDegrees(Math.atan2((targetY - currentY), (targetX - currentX)));

              degree = (90 - degree) - currentBearing;

              if (degree < 0)

                     degree = degree + 360;

 

              return degree;

使用math.atan2方法算出正切值从而计算出角度,然后与当前角度相减

 

 

       2. List<Double> angle = new ArrayList<Double>();

              int x1 = 0, x2 = 0, y1 = 0, y2 = 0;

              double tmpangle1 = 0;

              double tmpangle2 = 0;

              Iterator<Integer> x = xCoords.iterator();

              Iterator<Integer> y = yCoords.iterator();

              x1 = x.next();

              y1 = y.next();

              while (x.hasNext() && y.hasNext()) {

                     x2 = x.next();

                     y2 = y.next();

                     tmpangle1 = calculateBearingToPoint(tmpangle2, x1, y1, x2, y2);

                     tmpangle2 = tmpangle2 + tmpangle1;

                     tmpangle2 = (tmpangle2 < 360) ? tmpangle2 : (tmpangle2 - 360);

                     x1 = x2;

                     y1 = y2;

 

                     angle.add(tmpangle1);

              }

              return angle;

改进的针对list批量处理的方法

每次要重新计算当前指向角

      1. Problem 7: Convex Hulls

核心是使用该算法

通过对三个点的横纵坐标进行运算,得出中间的一个点是否位于另外两个点的凸侧

 

Convexhull 算一个课壳体,内套的函数才算实际函数convexHull2该函数又调用split把点分开

cTriangle测试通过

      1. Problem 8: Personal art

 

通过一个大循环,每次turtle移动距离发生小变化,同时控制转角,然后改变颜色。

 

 

 

 

      1. Submitting

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

上传到链接了远程仓库的本地仓库暂存区,

git add .

Git commit -m””

Git push -u origin master

    1. Social Network

社交网络图,该图是无向图,并且可以被扩展为有向图。A和B认识,则A与B连线,该图可扩展,加入顶点与边,存在方法能计算出图中任意两点间的最短距离,可以处理,不同的人有相同的名字,图中两点之间不存在路径,以及所求最小距离的两个点是同一个点,等异常。

由加边 加点 检测包含 测距等组成,

int getDistance (Person a,Person b)

boolean contain(Person a)

void addVertex(Person new_one)

void addEdge (Person a,Person b)

 

 

最终按照pdf上的例子做了测试

 

 

 

      1. 设计/实现Person类

Person类要求可以扩展的数据类型,即要求能够从无向图扩展为有向图,数据结构中朋友设定为两个即可实现有向。

       private String name;

       public Set<Person> friend;

       public boolean visited;

       public int index;

       public int distance;

      

      

       public Person(String name) {

              this.name = name;

              this.distance = 0;

              this.visited = false;

              this.friend = new HashSet<>();

       }

       public String getName(){

              return this.name;

       }

 

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

首先需要实例化一个FriendshipGraph对象,创建人创建关系,打印结果

 

       FriendshipGraph graph = new FriendshipGraph();

      

        Person ross = new Person("Ross");

        Person ben = new Person("Ben");

        Person kramer = new Person("Kramer");

        Person rachel = new Person("Rachel");

 

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

        //1

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

        //2

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

        //0

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

        //-1

}

也可改为通过键盘io读入人名建立关系,通过io,即先建立人对象

然后可建立对象之间的关系。

 

      1. 设计/实现测试用例

创建6个个体,创建边,验证边关系

              graph.addVertex(rachel);

              graph.addVertex(ross);

              graph.addVertex(ben);

              graph.addVertex(kramer);

              graph.addVertex(KKK);

              graph.addVertex(AAA);

             

             

              graph.addEdge(ross, ben);

              graph.addEdge(ben, ross);

              graph.addEdge(ross,KKK );

              graph.addEdge(KKK, ross);

              graph.addEdge(KKK, AAA);

              graph.addEdge(AAA, KKK);

              graph.addEdge(rachel, ross);

              graph.addEdge(ross, rachel);

 

                           

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

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

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

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

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

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

 

  1. 实验进度记录

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

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

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

日期

时间段

任务

实际完成情况

2020-02-25

14:00-15:30

编写问题1的isLegalMagicSquare函数并进行测试

按计划完成

2020-02-28

19:00-00:30

完成P1

延期1小时完成

2020-03-4

19:00-00:30

完成P2

按计划完成

2020-03-5

19:00-00:30

完成P2

按计划完成

2020-03-10

19:00-00:30

完成P3

按计划完成

2020-03-11

19:00-00:30

完成P3

按计划完成

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

遇到的难点

解决途径

根据输入的不同的字符串,读取不同的TXT,不知道java 如何替换语句中的文件名

 

 

在程序中放入5个文件名,用switch语句控制

如何从文件中读入矩阵,如何在不使用动态数组的情况下,根据不同文件,创建不同大小的数组,并将输入字符串输入流转为数字,存放在数组里。

 

使用bufferedread类进行文件流操作,先读入一行,利用split分词转为数字,幻方横纵相等,从而根据每行数据个数创建一个数组,有效节约空间。

第一次运行程序报错,不会使用eclipse调试,

 

 

 

学习调试,调试程序

测试P1所有功能

做修正

发现有些矩阵中包含小数

测试P1所有功能

做修正

发现矩阵中有数字间隔不是指标符号

P2多边形 角度 计算公式不记得了

上网查找资料,使用测试文件,通过

P2

不清楚凸包的的定义,没有思路,上网查找凸包定义,慢慢逐步测试,创建一些自己编写的小测试文件,测试通以后,逐步完善,最后通过测试。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值