HIT软构博客4-lab1记录与总结

​ 完成一个实验或小的项目使用java在需要的时候去搜索和看书比直接看很厚的书有意义一些,体验更加良好。自己对java的掌握不是很好,大一结束的夏天认真学习了java看了核心技术的卷I,但是里面的很多内容长时间不使用就忘记了。
​ 做了本次实验重新回顾了异常处理(开始写代码报错是因为没搞懂try catch块内部变量的作用域)、集合的用法、文件处理。此外,我第一次写代码要试着测试优先,还学习了使用junit测试,以前最多也只是写算法题把所有的测试样例通过就行。而这次实验对程序的健壮性有了很高的要求,这是我以前很少考虑的。写代码去解决问题是一件很有意思的事情。对我来说,远比学一些枯燥的数学和一些比较学术的问题有意思,觉得选软件工程方向比较好,希望能大三结束找到实习。

1.1 Magic Squares

1.读取5个提供的txt文档,判断txt文档中的数据能否构成一个幻方(行数等于列数,数字范围是从1到行数的平方且没有重复元素,每一行、列的和、两个对角线的和相等),如果是就返回true,如果不是返回false并说明原因。

2.对给定的generateMagicSquare函数进行扩充,产生一个要求的幻方写入到文件6.txt中,然后判断其是否是幻方,如果输入是奇数能产生幻方,输入偶数和负数return false。

1.1.1 isLegalMagicSquare()

按步骤给出你的设计和实现思路/过程/结果。

  1. 从文件中把读取要进行判断的矩阵读取出来,判断文件中数据是否满足幻方的定义(行列数相等的矩阵、无重复元素、元素范围从1到行数的平方)、矩阵中是否存在负数或小数、数字之间是否使用了\t分割,如果遇到这些不合法过程,就终止程序返回false,并在控制台打印提示信息。如果文件中幻方的格式合法,将幻方存储到一个int类型的二维矩阵numMatrix。

使用 BufferedReader类从文件字符输入流中读取文本并缓冲字符,以便有效地读取一行。用一个BufferedReader一次读一行,根据readLine次数计算出文件行数rowCnt。如果行数是0,不是幻方返回false。

定义一个numMatrix二维数组保存文件对应的幻方矩阵,定义一个visited数组,初始化为false。如果visited[i]是true,说明数字i已经被加入了numMatrix二维数组。

使用while循环,每次读取一行,记为字符串s,对这一行进行处理。使用split函数将这一行按照”\t”分割成若干字符串。如果分割出的字符串个数和rowCnt不相等,则可能这一行数字个数和行数不相等或者有两个数字不是用\t进行分割而是用了空格符,return false。

然后判断rowSplit字符串数组的每一个元素是不是小数、负数,如果是,不符合要求,打印提示消息return false。

    String[] rowSplit=s.split("\t");
    //保证当前这一行的数字个数与行数相等,否则return false
    if(rowSplit.length!=rowCnt){
        System.out.println("第"+(currentRow+1)+"行(行数从1开始计数)数字个数和行数不相等或者存在两个数字不是用\t而是用空格分割");
        return false;
      }
        //判断rowSplit的每一个元素是否包含了负数、小数
       for(int i=0;i

此外还有可能存在\t分割出的字符串还包含空格字符,对rowSplit[i]字符串使用valueOf函数可以判断出这种情况,当这个字符串含有空格,这个函数会抛出NumberFormatException,可以catch处理这种情况。如果这个字符串对应数字合法,将它保存到对应numMatrix中的位置,使用一个计数器currentRow记录当前处理的是哪一行。

如果解析出的数字出现0或大于行数平方的数或有两个重复数字,返回false。

for(int i=0;irowCnt*rowCnt||visited[numMatrix[currentRow][i]]) {
                System.out.println("出现0或大于行数平方的数或一个数字重复出现");
                        return false;
                    }
                    visited[temp]=true;
     }
  1. 文件对应的幻方已经存储在了nunMatrix矩阵中,接下来进行判断,这个矩阵是否对应了一个幻方(每一行的和、每一列的和、两个对角线的和都相等),如果是幻方返回true,不是就返回false并打印提示信息。

已知行数和正方形矩阵,先算出两个对角线的值看是否相等,不等就return false。

然后计算每一行的和,如果和对角线和不等就return false,最后计算每一列的和,如果和对角线和不相等就return false。

  1. 以上所有出现错误的情况都没有出现,return true。

结果:

HIT软构博客4-lab1记录与总结

1.1.2 generateMagicSquare()

按步骤给出你的设计和实现思路/过程/结果。

设计和思路:

(1)generateMagicSquare函数通过一个奇数来构造特定的幻方矩阵,把1到行数平方的数放入矩阵中,先选定一个起始位置(第一排中间),然后沿着副对角线方向沿着右上方向前进,每穿过n格后向下一格,再次向右上前进,填入到二维数组中。

(2)指导书要求我们对给定的上述代码进行修改,并且能将结果输出到文件6.txt中。输入参数为负数和偶数时,要能够优雅退出,函数输出为false。若不修改,程序会在输入为负数时,因为构造的二维数组下标为负而产生异常并强行退出;在输入为偶数时,会在填完某n个数之后,row++出现下标越界的情况,产生异常并强行退出。

过程:

(1)在函数开始时判断如果参数是负数或小数,return false。

(2)使用给定算法对应代码计算出幻方矩阵。

(3)使用FileWriter类的对象和BufferedWriter类的对象实现写入文件。

HIT软构博客4-lab1记录与总结

结果:

输入奇数:7

HIT软构博客4-lab1记录与总结

1.2 Turtle Graphics

利用实验已经给出的代码,实现实验要求的方法,最后设计用已有的函数设计图形。Turtle Graphics是模仿python里的画图库写的一个接口Turtle, 并且可以支持forward, turn, color, draw四种方法,。

1.2.1 Problem 1: Clone and import

管理本地开发:

  1. git add ;
  2. git commit -m ” ” ;
  3. git push origin master.

1.2.2 Problem 3: Turtle graphics and drawSquare

利用已给的代码中的方法forward和turn,画正方形。Turtle类的一个对象初始方向是y坐标轴正方向,让turtle每次移动sideLength后向转动90°(顺时针),画完四条边即可。

 turtle.forward(sideLength);

​    turtle.turn(90);

​    turtle.forward(sideLength);

​    turtle.turn(90);

​    turtle.forward(sideLength);

​    turtle.turn(90);

​    turtle.forward(sideLength);

HIT软构博客4-lab1记录与总结

1.2.3 Problem 5: Drawing polygons

实现calculateRegularPolygonAngle函数,如果边数(sides)小于等于2,return 0,否则return (sides-2)*180.00/sides。

使用上面的函数计算出多边形的内角大小,根据边数每次先forward边数长度,然后turn转弯内角的大小。

turtle.forward(sideLength);
        double degree=180-calculateRegularPolygonAngle(sides);
        for(int i=1;i

HIT软构博客4-lab1记录与总结

1.2.4 Problem 6: Calculating Bearings

首先需要实现calculateBearingToPoint函数:根据给出的五个参数:当前方向,目前点横,纵坐标,目标点横,纵坐标,要求返回从当前点要前进到目标点需要顺时针转动的角度。思路是先由反正切函数求出向量与y正半轴的夹角的绝对值,然后根据不同象限分情况讨论它与y正轴的夹角,具体是:

public static double calculateBearingToPoint(double currentBearing, int currentX, int currentY,int targetX, int targetY) {
        //当前点和目标点重合,不需要转向
        if(currentX==targetX&¤tY==targetY)return 0.0;
        double degree=Math.atan2(targetY-currentY, targetX-currentX)/Math.PI*180;// atan2函数返回与x轴正向的夹角,范围是-PI到PI
        if(targetX-currentX<0&&targety-currenty>0) {//&#x5DE6;&#x4E0A;&#x65B9;&#x7684;&#x8C61;&#x9650;
            degree=270+180-degree;
        }else {//&#x5269;&#x4E0B;&#x4E09;&#x4E2A;&#x8C61;&#x9650;&#xFF08;&#x53F3;&#x8FB9;&#x4E24;&#x4E2A;&#x4E0B;&#x9762;&#x4E24;&#x4E2A;&#xFF09;
            degree=90-degree;
        }
        double ans=degree-currentBearing;
        return ans<0? ans+360:ans; < code></0?></0&&targety-currenty>

1.2.5 Problem 7: Convex Hulls

根据实验要求,点个数小于等于3时认为所有点构成了凸包,把所有点返回。

点的个数大于3时,所有点中最左下的点必定在凸包内,此时查找点集中转弯的时候,到路线上下一个点的转弯角度(顺时针)相比于其他所有点是最小的,若出现使得旋转角度同样小的点,则取离当前点更远的点。

 //先把最左下的结点加入凸包,从points1移走
        convex.add(mostLeftDownPoint);
        points1.remove(mostLeftDownPoint);
        //一直往凸包列表加入结点,直到下一个要加入的结点回到最左下结点。
        //先把最左下结点移出points1,在从最左下的找到第二个结点时把最左下结点加回points1中,这样结束条件才能是当前要加入的结点又是最左下结点,完成了凸包的一圈
        //如果不先把mostLeftDownPoint移出points1,那么第一次从preAdd找下一个要加的结点就还是mostLeftDownPoint
        //preAdd记录上一次加入的结点
        Point preAdd=mostLeftDownPoint;
        Point tempAdd=null;
        int cnt=0;
        do {
            if(cnt==1)points1.add(mostLeftDownPoint);
            double minDegree=360;
            double maxDistance=Double.MIN_VALUE;
            //选出下一个要加入凸包的结点tempAdd
            tempAdd=points1.get(0);
            for(Point p:points1) {
                double degree=calculateBearingToPoint(0,(int)preAdd.x(),(int)preAdd.y(),(int)p.x(),(int)p.y());
                double distance=Math.pow((p.y()-preAdd.y()), 2)+Math.pow(p.x()-preAdd.x(), 2);
                if(degreemaxDistance) {//if,在上面条件成立的时候了也要继续判断,如果两个有一样的distance,要选最大的distance
                    maxDistance=distance;
                    tempAdd=p;
                }
            }

            convex.add(tempAdd);
            cnt++;
            preAdd=tempAdd;
            points1.remove(preAdd);
        }while(tempAdd!=mostLeftDownPoint);
Set ans=new HashSet<>();
        ans.addAll(convex);
    return ans;

1.2.6 Problem 8: Personal art

利用多种颜色(存储进colors数组中用来交替使用,选了8种),用idx=i%8从数组中选择此步我要用的颜色。

每次前进长度为i,i逐渐增大,每次前进结束后顺时针转向90.5度。

PenColor[] colors= {PenColor.GRAY,PenColor.RED,PenColor.PINK,PenColor.ORANGE,
                PenColor.YELLOW,PenColor.GREEN,PenColor.CYAN,PenColor.BLUE};
        int idx=0;//0...7
        for (int i = 0; i < 700; i++) {
            turtle.forward(i);
            idx=i%8;
            turtle.color(colors[idx]);
            turtle.turn(90.5);
        }

HIT软构博客4-lab1记录与总结

本次任务要求实现Person和FriendshipGraph两个类,用FriendshipGraph来模拟社交网络,实现函数计算出每两个Person之间的最短路径。任务分为两部分,一个是实现这两个类,一个是写出各方法对应测试用例。

1.3.1 设计/实现FriendshipGraph

给出你的设计和实现思路/过程/结果。

HIT软构博客4-lab1记录与总结

设计:FriendshipGraph类包含两个私有字段people和nameSet,people是一个列表,记录加入到社交网络中的人,nameSet是一个集合,存储加入社交网络中的人的名字。

该类有三个public方法:

  1. addVertex:向社交网络中加入人。
  2. addEdge:向社交网络中的人之间添加边(朋友关系)。
  3. getDistance:获取社交网络中两个人之间的最短距离。

实验要求当向社交网络中加入已经存在的名字的人会违反” Each person has a unique name “的约束条件,因此addVertex时判断要加入的人的名字是否已经包含在nameSet中,如果已经存在,提示程序出错并结束运行。

HIT软构博客4-lab1记录与总结
HIT软构博客4-lab1记录与总结

实现getDistance:

  1. 如果p1==p2,距离是0.

  2. 使用队列实现广度优先算法,从p1开始一圈一圈找朋友看有没有p2,先把p1加入到队列中,使用一个Map

  3. 如果队列空了,还是没找到p2,他们不是朋友,return -1。

1.3.2设计/实现Person类

给出你的设计和实现思路/过程/结果。

HIT软构博客4-lab1记录与总结

该类包含两个私有字段,name记录名字,friends是一个哈希集合,存储所有朋友。该类还有四个方法,Person是构造方法,getName返回名字,addFriend添加朋友,getfriends返回所有朋友的列表。

1.3.3 设计/实现客户端代码

(1)

HIT软构博客4-lab1记录与总结

(2)如果将第 3 行引号中的”Ross”替换为”Rachel”,你的程序会发生什么?

这其实违反了” Each person has a unique name “的约束条件。修改你的

FriendshipGraph 类和 Person 类,使该约束能够始终被满足(意即:一旦该

条件被违反,提示出错并结束程序运行)。

img

(4)如果将上述代码的第 10 行注释掉(意即 rachel 和 ross 之间只存在单向的社交关系 ross‐>rachel),请人工判断第 14-17 行的代码应输出什么结果?让程序执行,看其实际输出结果是否与你的期望一致?

人工画图判断,应该为 -1、-1 、0、-1

我增加了代码判断ross到rachel的距离 ,人工判断应该是1。

HIT软构博客4-lab1记录与总结

实际输出结果和我的预期一致是-1、-1、0、-1、1

1.3.4 设计/实现测试用例

给出你的设计和实现思路/过程/结果。

  1. 测试addVertex,向社交网络中加入一人Alice,用assertEquals判断加入成功;再加入第二个人Bob,用assertEquals判断加入成功。
  2. 测试addEdge,向社交网络中加入两人(one和two),再添加其朋友关系(双向),两次运用assertEquals判断其关系已成功加入;
  3. 测试getDisdance,构造一个较复杂的社交网络,再调用assertEquals判断其最短距离计算准确。自行构造的社交网络图示意如下:

HIT软构博客4-lab1记录与总结

Original: https://www.cnblogs.com/aurora7301/p/16311473.html
Author: aurora7301
Title: HIT软构博客4-lab1记录与总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/684078/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 研发过程中的文档管理与工具

    写文档也是技术活 01:实践 对于多数开发同学来说,很多时候即讨厌没有研发文档,但是自己又不愿意常写文档,痛且倔强着; 程序员该不该写文档,与争论哪种编程语言最好一样,想撕的嘴不留…

    技术杂谈 2023年7月23日
    062
  • 基于Vue cli生成的Vue项目的webpack4升级

    前面的话 本文将详细介绍从webpack3到webpack4的升级过程 相比于webpack3,webpack4可以零配置运行,打包速度比之前提高了90%,可以直接到ES6的代码进…

    技术杂谈 2023年5月31日
    0101
  • webstorm中js文件被识别成txt类型

    问题描述: webstorm中index.js文件被识别成txt格式,如下图。 原因: webstorm中js文件被识别成txt文件,原因在于txt类型识别了以当前js文件名命名的…

    技术杂谈 2023年5月31日
    088
  • PyQt5 QCommandLinkButton

    ################################ PyQt5中文网 – PyQt5全套视频教程 # https://www.PyQt5.cn/ # 主讲: 村长 #…

    技术杂谈 2023年5月31日
    093
  • Vue中预览HIKVSION海康威视摄像头时ip不通浏览器卡死问题解决

    场景 SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/ar…

    技术杂谈 2023年5月31日
    0138
  • C# 可视化与自定义控件开发

    和上篇文章一样,基本上以后不会再去弄C#了,所以2年前的资料,都拿出来无偿贡献了。 有两篇整理的资料,目录如下图所示,可以点击此处(C_Sharp_可视化控件开发.rar)下载。 …

    技术杂谈 2023年5月30日
    0108
  • mysql

    基础篇 通用语法及分类 DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段) DML: 数据操作语言,用来对数据库表中的数据进行增删改 DQL: 数据查询语言,用来查询数…

    技术杂谈 2023年7月25日
    063
  • 「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之动态表单(五)

    基于Vue和Quasar的前端SPA项目实战之动态表单(五) 回顾 通过上一篇文章基于Vue和Quasar的前端SPA项目实战之序列号(四)的介绍,我们已经完成了元数据中序列号的增…

    技术杂谈 2023年7月24日
    083
  • 互联网行业的常用黑话,你知道几条?

    往期推荐 身为一名新时代的互联网工作人员,怎么能对这个行业的黑话一无所知呢?下面我给大家整理了互联网行业的基本”黑话”,看看你知道几条。 一、互联网人知名大…

    技术杂谈 2023年5月31日
    0110
  • @Aspect

    AOP是指在程序运行期间动态地将某段代码切入到指定位置并运行的编程方式。 AOP详解可参考:https://blog.csdn.net/javazejian/article/det…

    技术杂谈 2023年7月24日
    084
  • 统计分析工程的依赖项

    最近在完成自己的想为自己的开源项目 application-center增加一个功能: 统计某个jar在哪些工程中被使用 统计某个版本的jar在哪些工程中被使用 应用场景 为什么我…

    技术杂谈 2023年6月1日
    091
  • 跨域

    同源策略指三个相同:协议相同、域名相同、端口相同,有一个不同即非同源。 主域与子域、域名与域名对应的IP。都是非同源的 同源策略可以算是web安全的基石,没有同源策略就么有安全可言…

    技术杂谈 2023年5月31日
    079
  • QQ音乐歌单获取所有歌名tempmonkey

    QQ音乐歌单获取所有歌名tempmonkey csharp;gutter:true; // ==UserScript== // @name 歌名获取 // @namespace h…

    技术杂谈 2023年5月31日
    084
  • 托付

    我们先无论这个标题怎样的绕口。也无论托付到底是个什么东西,来看以下这两个最简单的方法,它们只是是在屏幕上输出一句问候的话语: 如果这个程序须要进行全球化。哎呀,不好了,我是中国人,…

    技术杂谈 2023年5月31日
    0118
  • 消息队列面试题要点(转)

    复习要点 本文主要围绕如下几点进行阐述: 为什么使用消息队列? 使用消息队列有什么缺点? 消息队列如何选型? 如何保证消息队列是高可用的? 如何保证消息不被重复消费? 如何保证消费…

    技术杂谈 2023年5月31日
    086
  • MIUI 蓝牙不能微信钉钉通话

    MIUI 系统不能 使用蓝牙耳机进行通话(微信,钉钉),音乐没有问题; 问题: 打电话能用蓝牙,听音乐也没有问题; 发现只有 开会的时候和微信语音视频的时候不能,只能听筒和外放; …

    技术杂谈 2023年5月31日
    0210
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球