哈工大2021春软件构造实验总结

哈工大2021春软件构造实验总结


一、实验一

1. 实验概述

1.1 Magic Squares

  1. 介绍:n阶幻方是一个n*n矩阵,其中矩阵的数通常为不同的整型数,每一行之和,每一列之和,两条对角线之和,都需要保持一致。
  2. 本任务要求对幻方进行判断,并要求能够处理输入文件的各种特殊情况,例如:文件中的数据不符合 Magic Square 的定义(行列数不相等、并非矩阵等)、矩阵中的某些数字 并非正整数、数字之间并非使用\t分割等。若遇到这些情况,终止程序 执行(isLegalMagicSquare 函数返回 false),并在控制台输出错误提示信息。

1.2 Turtle Graphics

  1. 该任务是通过调用turtle的方法库,主要是方法forword(units)和turn(degrees),实现一系列的画图操作
  2. 凸包问题的解决
    (1)介绍:凸包问题是在平面上的一系列点中,找到一个最小的点集,使之能够包围所有的点,类似于边界,而这一最小点集即平面上这些点的凸包。
    (2)解决思路:采用Jarvis步进法,先找到最左下角的点(点的X分量最小,若多个点X分量相同,选择其中Y分量最小的点),则它一定是凸包的一个顶点。接着相对于前一个点,找到两点连线与上一连线夹角最小的点。在一搜索过程中,需要遍历凸包外其他所有的点。重复以上过程,直到回到起始点。特别的,三个点以内的凸包为其本身。
    (3)实现代码
for(Point k : points)
                {
                    if(k.equals(currentPoint))
                        continue;
                    //找到最近加入凸包的点与凸包外所有点之间转动角度最小的点,加入凸包
                    angle = calculateBearingToPoint(preAngle, (int)currentPoint.x(), (int)currentPoint.y(), (int)k.x(), (int)k.y());
                    if (nextAngle > angle) {
                        distance = Math.pow(k.x()-currentPoint.x(), 2)+Math.pow(k.y()-currentPoint.y(), 2);
                        nextAngle = angle;
                        nextPoint = k;
                    }
                    //如果角度相等,选择距离最远点
                    else if (nextAngle == angle) {
                        if(distance < (Math.pow(k.x()-currentPoint.x(), 2)+Math.pow(k.y()-currentPoint.y(), 2)))
                        {
                            distance = Math.pow(k.x()-currentPoint.x(), 2)+Math.pow(k.y()-currentPoint.y(), 2);
                            nextPoint = k;
                        }
                    }
                }
  1. 个性化画图展示

在这里插入图片描述

1.3 Social Network

本任务刻画的社交网络是无向图,FriendshipGraph代表社交网络中的朋友关系,并且能够计算图中两人的社交距离,Person用来定义社交网络的对象。
(1)main函数实现
在这里插入图片描述

2. 实验感受

(1)初次接触软件构造的实验,最大感受就是应该提前学习Java编程语言;
(2)遇到问题多思考,多与同学交流经验,你遇到的困难(Git、Github等)有可能别人已经遇到并已经解决

二、实验二

1. 实验概述

1.1 Poetic Walks

  1. 任务描述
    此任务第一部分是实现类型Graph,它是带有标记顶点的可变加权有向图的抽象数据类型。
    可变图:可以在图中添加和删除顶点和边
    有向边:边从源顶点到目标顶点
    加权边:边与正整数权重相关联
    标记的顶点:顶点通过某种不可变类型的标签来区分,例如它们可能有String名称或IntegerID

  2. 可变加权有向图的接口的实现分为两种,一种是以边为对象,另一种是以顶点对象,要求独立完成所需要的方法功能。

  3. GraphPoet: 用语料库初始化,然后在给定输入的情况下,使用由该语料库定义的词亲和图来诗意地转换输入,其中:顶点是不区分大小写的单词,并且边权重是有序的邻接计数。
    (1)实现结果
    在这里插入图片描述

1.2 Re-implement the Social Network in Lab1

  1. 任务描述:FriendshipGraph中应提供addVertex()、addEdge() 和getDistance()三个方法:针对addVertex() 和addEdge() ,需要尽可能复用ConcreteEdgesGraph或ConcreteVerticesGraph中已经实现的add()和set()方法,而不是从0开始写代码实现或者把你的Labl相关代码直接复制过来;针对getDistance()方法,请基于你所选定的ConcreteEdgesGraph或ConcreteVerticesGraph的rep来实现,而不能修改其rep。
  2. 通过将社交网络定义ConcreteEdgesGraph或ConcreteVerticesGraph,再调用第一部分实现的方法实现社交网络的方法功能即可。
    (1)社交距离的设计思路:
    从person_1起,通过广度优先搜索+队列遍历社交图,每到新一层的社交网络,距离+1,直至到person_2,其中某人的直接朋友可以采用方法sources(L target)或者targets(L source)得知;
    (2)社交距离的实现:
while (!queue.isEmpty()) {
            Person outQueuePerson = queue.poll();
            socialDistance = Path.get(outQueuePerson);

            //对于出队人的所有直接朋友
            for (Person e : personGraph.sources(outQueuePerson).keySet()) {
                if (!Path.containsKey(e)) {
                    Path.put(e, socialDistance + 1);
                    if (e == person_2)
                        return Path.get(person_2);
                }
                queue.offer(e);   //直接朋友全入队
            }
        }

2. 实验感受

(1) 面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?

面向过程是以“算法”为中心,通过使用函数实现各个步骤,并依次调用实现的函数解决问题;
面向对象是以“对象”为中心,在设计好相应的对象后(对象的属性),将对象在整个问题中的相关行为封装到一起(对象的方法),然后各个对象共同将整个事情完成;

区别:

  • 面向过程的出发点是综合分析,面向对象的出发点是构造对象。
  • 面向过程是一种自顶向下的编程,面向对象是将事物高度抽象化,所以首先要建立抽象数据类型(ADT)。
  • 面向过程传递的是参数或全局变量,面向对象的直接调用方法

(2)在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?

  • 提前写好测试用例,可以一开始就明确用户需求,根据需求明确编码,而在编码过程中,也可以及时根据测试进行核实,确认其是否符合要求,测试可以去除程序本身bug之外脱离用户需求的问题,即步步为赢。
  • 对于初次使用此种方法,使用起来有些别扭,需要一定的时间来消化,最重要的是要明确ADT及其规约。

(3)为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?

  • 首先能够明确ADT的书写规范和用户需求,其次有利于及时记录编写者的思考和灵感,以便编写者以后或者其他人使用和改进。

三、实验三

1. 实验概述

1.1 管理系统的介绍

  1. 应用一:值班表管理(DutyRoster):
    对于一个单位的 n 个员工,在每个时间段内,每天只能安排唯一一名员工在单位值班,且不能出现某天无人值班的情况(值班表不能出现空缺);每个员工若被安排值班 m 天 (m>1),那么需要安排在连续的 m 天内。值班表内需要记录员工的名字、职位、手机号码,以便于外界联系值班员。

  2. 应用二:操作系统进程调度管理(ProcessSchedule)
    计算机上有一个单核 CPU,操作系统可以创建多个进程,它们被调度在 CPU 上执行,操作系统可自由决定在各个时段内执行哪个线程。操作系统可挂起某个正在执行的进程,也可以在后续时刻恢复执行被挂起的进程。
    注意:每个时间只能有一个进程在执行,其他进程处于休眠状态(被挂起);一个进程的执行可以被分为多个时间段;在特定时刻,CPU可以“闲置”,即操作系统没有调度执行任何进程;操作系统对进程的调度无规律,可看作是随机调度

  3. 大学课表管理(CourseSchedule)
    针对某个班级,其课程都是周期性出现的,而且周期数与学期的总周数保持一致。所以每学期的第一天应该从周一开始,否则会破坏课程的周期性。对于每一门课而言一门课程每周可以出现 1 次,也可以安排多次且由同一位教师承担并在同样的教室进行;允许课表中有空白时间段(未安排任何课程);考虑到不同学生的选课情况不同,同一个时间段内可以安排不同的课程,一位教师也可以承担课表中的多门课程

1.2 管理系统的实现策略

  1. DutyIntervalSet的结构
    值班表管理系统继承于CommonIntervalSet,并实现IDutyIntervalSet,CommonIntervalSet是三个app中可复用的方法,而IDutyIntervalSet通过不同接口之间的组合,实现了三个差异性(空白,重复,周期)的结合。
    在这里插入图片描述
    通过在DutyIntervalSet中定义nbis,npis,nois等属性,并在构造器中建立委托关系,进而做到永久地绑定,避免继承大量无用的方法。
  2. ProcessIntervalSet
    操作系统进程管理系统继承于CommonMutiIntervalSet,并实现IProcessIntervalSet,CommonMutiIntervalSet是三个app中可复用的方法,而IProcessIntervalSet通过不同接口之间的组合,实现了无周期,无重叠。
    在这里插入图片描述
  3. CourseIntervalSet
    大学课表管理系统继承于CommonMutiIntervalSet,并实现I CourseIntervalSet,CommonMutiIntervalSet是三个app中可复用的方法,而ICourseIntervalSet通过不同接口之间的组合,实现了有周期。

在这里插入图片描述

1.3 管理系统的APP实现

APP采用IDEA下的GUI进行开发设计。

  1. 排班管理系统
    (1)以下为排班管理系统的框架:
    在这里插入图片描述
    (2)APP的界面为:
    在这里插入图片描述
  2. 操作系统的进程调度管理系统
    以下是操作系统的代码框架:
    在这里插入图片描述
    以下是课表管理系统的APP界面:
    在这里插入图片描述
  3. 大学课表管理系统
    以下是课表管理系统的代码框架:
    在这里插入图片描述
    以下是课表管理系统的APP界面:
    在这里插入图片描述

2. 实验感受

通过软件构造这门课,我的编程能力有了进一步的提高,也深刻感受到面向对象编程和面向过程编程的差异,还有可复用编程给程序员带来的巨大福利,不过我的课堂感受就是课堂上的例子真的超级重要,无论是对知识点的理解,有时候听课听的稀里糊涂,看完示例有时候会茅塞顿开,而且示例对实验也有很大的帮助,最后一点就是提前进行Java入门很重要;


总结

本文对哈工大2021春软件构造实验进行了简要概述,并简要介绍了实验的部分实现策略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值