[2022软工第三次作业]结对编程项目——最长英语单词链

项目 内容
本作业所属课程 2022年北航敏捷软件工程教学实践
本作业要求 结对编程项目-最长英语单词链
个人课程目标 学习到软件工程的方法论,了解整个过程,并进行亲自实践
本作业在哪个具体方面帮助我实现目标 结对协作能力,Visual Studio开发工具使用技能,代码进行单元测试和性能分析,认识到模块解耦的重要意义

软件工程结对编程作业

项目信息

  • 教学班级:周五班
  • 项目地址:https://github.com/ZerglingChen3/LongestEnglishWordChain
    成员:陈纪源 薛欣

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60
· Estimate · 估计这个任务需要多少时间 60
Development 开发 2030
· Analysis · 需求分析 (包括学习新技术) 60
· Design Spec · 生成设计文档 60
· Design Review · 设计复审 (和同事审核设计文档) 150
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20
· Design · 具体设计 120
· Coding · 具体编码 900
· Code Review · 代码复审 240
· Test · 测试(自我测试,修改代码,提交修改) 480
Reporting 报告 140
· Test Report · 测试报告 60
· Size Measurement · 计算工作量 20
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60
合计 2230

接口设计

设计理念

  • 信息隐藏(Infromation Hiding):信息隐藏原则是将一些重要信息或者不希望被其他人使用的属性包装起来,只暴露相应的接口完成对类中属性的修改和访问。这种方法可以使调用者不再需要关注对象内部的实现方法,只需要关注接口的设计即可完成调用,同时防止了外部对对象内部的调用进而破坏对象的完整性或者约束。我们在自己的项目中对于边封装了Edges类,图封装了Graph类,对外提供了相应的访问结构的方法。
  • 接口设计(Interface Design):接口设计中的基本原则包括明确接口职责和职责单一性原则。一个良好的接口一定要明确接口中每一个参数,调用者在调用时不应该产生歧义,并且调用时能快速得到结果。接口中包含的参数应该是最简单的,不应该把多个任务放在同一个接口中。在我们的项目中,我们建立了参数解析和建图两个不同的接口,并明确了接口的输入输出,这样明确了模块之间的交流方式。
  • 松耦合(loose coupling):松耦合是指模块之间联系较少,对于其中一个模块的修改对其他模块的影响应该比较少,模块之间仅用提供的接口进行联系。松耦合的重要意义在于需求的变化,这样修改的部分会尽可能减少。在我们的项目中,我们将模块分成了输入模块、核心模块和输出模块,模块之间互相独立减少依赖。

计算模块接口的设计和实现

存储
  • 单词类(Word)中储存的是单词原本的字符串信息、首尾字母以及长度,外界可以通过公共方法读取这些信息,但不能修改。
  • 边类(Edge)中存储了一条边的端点、权值、邻接边以及对应的单词。外界可以通过公共方法读取这些信息,但不能修改。
  • 图类(Graph)中存储了一张图中的边、点、点的权重、自环索引、常规边索引、各点自环数目。外界可以通过公共方法读取这些信息,可以调用创建常规边和自环的方法进行增添。
建图

我们将每个字母抽象成一个点,单词则是从首字母所在点到尾字母所在点的一条边。单词的长度作为对应边的边权。同时,我们需要特殊记录每个点的自环。

产生所有单词链

gen_all_chain接口的实现如下图所示,首先处理原始单词列表,建立图,枚举所有出现过的字母作为起点,然后进行dfs搜索得到所有路径,即可得到所有单词链。

产生首字母不重复的单词链

gen_chain_word_unique接口的实现如下图所示。由于首字母不重复,因而在答案中每个点仅使用一次,并且题目中要求合法的输入中不包含环。

我们利用原始单词列表建图,所得的图必然是DAG,然后求出图的拓扑序,并按照拓扑序进行动态规划,求最长路径。转移方程为 d p [ i ] = d p [ j ] + 1 dp[i] = dp[j]+1 dp[i]=dp[j]+1,其中需要满足 e ( j , i ) ∈ G e(j, i) \isin G e(j,i)G t o p o [ i ] > t o p o [ j ] topo[i] > topo[j] topo[i]>topo[j]。并且在转移的过程中,我们需要记录 p r e E d g e [ i ] preEdge[i] preEdge[i]表示当前 d p [ i ] dp[i] dp[i]是由哪条边转移而来的,以便于后面逆推产生单词链。

特殊的,只有末尾的字母是允许有自环的,因而在dp结束后,需要特判每一个字母是否有自环,如果有,则dp值需要加1。

逆推答案时,首先判断是否包含自环,然后根据 p r e E d g e [ i

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值