结对项目——Core设计与实现
写在前面:关于结对编程
结对编程我一直认为是一种非常好的合作方式,他的形式主要是由一个人负责代码编写,另一个人则在一旁即时对写下的代码进行审查,这样可以大大减少代码实现方面的错误。
这次我的结对伙伴是小芦荟(学号后四位为1221)。他平时喜欢打篮球,打的也挺不错的,三国杀也是高手(都100多级了),是一个比较靠谱的人。但是在编程这方面他可能不太擅长,因此这次结对项目就变成了我一个人写,他在旁边看着……不过有时他也会指出我的代码中非常明显的问题,这也保证了我的代码正确性较高。设计的单元测试几乎全是一次通过。
附结对编程图片:
关于Design by Contract、Information Hiding
本次结对项目要求对上次的个人项目进行封装,并写一个界面来调用这些封装好的函数。这就需要我们对相关接口制定一个规范,我和另一个队伍(pair16)的同学约定好了代码接口,便于之后的测试。
对于Information Hiding原则,我们这次其实做的并不好,所有的类属性也均为public,这主要考虑到本次程序会封装为程序编写的方便。
我们core部分均采用Win32 Console Application实现,图形界面部分均采用MFC Application实现。core编写完成,测试完成后,生成dll并提供两个接口,用来实现要求的两个功能。接口的定义均提前约定。
关于接口定义、dll封装的具体内容在第二篇博客中会详细介绍。
设计与实现
算法设计
我们本次项目沿用了上次我的个人项目的设计,只不过在其基础上添加了对负数、有无括号、有无乘除法的限制,以及对运算符个数的限制。
具体来说,对于四则运算题目生成的部分:
- 获取到传入的参数限制,包括运算符个数限制、数值限制、有无分数、有无负数
- 递归生成一个表达式树
- 递归进行表达式的正确性检验(是否出现了负数、除0以及不能整除的情况)
- 递归对表达式树进行最小表示
- 如果得到的算式之前没有生成过,则将该算式加入到生成队列中。
- 如果当前的表达式个数已经达到要求,则将表达式与答案返回。
其中,在生成表达式树的过程中,首先需要判断树中当前的节点是否为分支节点(即运算符)。如果当前的树的总结点数为0,那么该节点必须为分支节点,如果当前树中的分支节点已经打到了要求的上限,则该节点必须为叶子结点(即操作数)。有了这个信息之后,针对当前结点的类型不同,就可生成对应的结构,之后如果当前结点为分支节点的话,就递归生成其左右子树。
在对表达式进行正确性检验的过程中,如果当前结点为叶子节点,那么我们仅需要检验这个叶子结点的数值是否满足要求。否则,先递归对它的左右子树进行正确性检验,在确保左右子树正确的情况下,检验当前结点的运算是否会造成不合法的情况,如果有的话则进行修复。
在对表达式最小表示的过程中,同样是先递归对其左右子树进行最小表示,之后再看,如果当前结点为'+'或'×',则判断一下他的两个子树的hash值大小,在不改变运算顺序的前提下使表达式变为最小标识的形式。
检验算式仍然采用了第一次作业的形式,以一个STL的set来存放最小表示后的字符串,通过字符串的比较进行判重。
对于计算表达式结果的功能,仍然没什么好说的,采用了STL的两个栈来维护。
具体实现
首先来看UML类图:
本次项目中共用到了4个类。CFactor类是对上次Factor的一个扩展,加入了对负数的支持。CExpressionNode类是表达式树的一个节点。CExpression类是表达式树,CProblemSet类对两种操作进行了封装。这四个类形成如上的关联关系。
根据这个这个类图,顺便说一下本次结对项目的代码规范:
- 类名均以 C 开头,大括号不换行
- 类属性以 m _ 开头
- 类方法均使用小写字母,单词之间采用下划线分开。
- 每个类方法前必须有必要的注释
这样的规范主要考虑到本次项目要与MFC结合,因此使用了一些Win32的代码习惯。
CFactor类中,我重载了各种运算符,包括输入输出、四则运算和比较运算符。重载运算符后会大大降低编程复杂度,但是过多地采用流输入输出可能会对程序效率造成影响……这也是我在测试的时候才发现的问题。
CExpressionNode类则没什么好说的,就是储存了一个树节点的信息,包括其左右子树、当前结点的运算符以及当前子树的表达式的值。
CExpression类则是一个表达式树,他内部采用了一个CExpressionNode类型的数组用来存储表达式中的所有结点,并通过new_node
方法实现获取一个新节点的操作。这样做避免了每次的动态内存分配,一定程度上可以提高程序效率,但是这样做则要求表达式不能太长,不过在实际应用中不会用到太长的表达式。
CProblemSet类则没什么好说的了,他实例化了一个CExpression类的对象,每次调用该类的 build_expression_tree
方法生成一个表达式并使用set进行重复检验。
单元测试
本次项目的基础就是CFactor类,如果该类的实现有问题,那么所有功能都不能正常工作,因此我主要对该类进行了单元测试。
VS2013单元测试我也是第一次使用,不知道为什么Managed Test Project 创建后会无法连接C++console Application的代码,最后采用了 Native Unit Test Project 来做单元测试,它的语法与Managed Test Project略有不同,但是也很简单,我针对CFactor类的各种方法写了37条Unit Test, 并且全部通过了。
代码覆盖率:
注:我的VS2013是社区版,没有代码覆盖率分析工具,所以在我编写完测试用例后,借用了同寝室的另一个人的电脑来测试并进行代码覆盖率检验。
结对项目——Core设计与实现的更多相关文章
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
项目开发中的一些注意事项以及技巧总结 1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...
- 系统分析与设计结对项目——WordCount
结对项目完成WordCount 合作者:201631062507 201631062526(学号) 代码地址:https://gitee.com/WordCountMC/WordCountTeam ...
- 高级四则运算器—结对项目反思(193 & 105)
高级四则运算器—结对项目反思(193 & 105) 本周我和一位韩国同学(71061105)一起结对编程完成了我们的结对项目——高级的小学四则运算题目生成器. PSP表格 PSP2.1 P ...
- 结对项目——图形界面实现与dll动态链接
先来一发软件截图~~~ 生成题目的界面 测评界面 第三块本来准备做一个文件历史记录的界面,但是由于时间不够,暂时还没做完. 图形界面的设计与实现 由于对传统的对话框风格不太满意,所以这次作业的图形界面 ...
- [2017BUAA软工助教]结对项目小结
2017BUAA结对项目小结 一.作业链接 http://www.cnblogs.com/jiel/p/7604111.html 二.评分细则 1.注意事项 按时间完成并提交--正常评分 晚交一周以内 ...
- [buaa-SE-2017]结对项目-数独程序扩展
结对项目-数独程序扩展 step1~step3:github:SE-Sudoku-Pair-master step4:github:SE-Sudoku-Pair-dev-combine step5:g ...
- [2017BUAA软工]结对项目
软工结对项目 一. Github项目地址 https://github.com/crvz6182/sudoku_partner 二. PSP表格 Psp personal software progr ...
- [2017BUAA软工]结对项目:数独扩展
结对项目:数独扩展 1. Github项目地址 https://github.com/Slontia/Sudoku2 2. PSP估计表格 3. 关于Information Hiding, Inter ...
- [BUAA_SE_2017]结对项目-数独程序扩展
结对项目-数独程序扩展 Runnable on x64 Only sudoku17.txt 须放置在可执行文件同目录中,可移步以下链接进行下载 Core-Github项目地址 GUI-Github项目 ...
随机推荐
- Maven 变量及常见插件配置详解
Maven 的 pom.xml 常用 变量 插件 配置 详解 一.变量 - 自定义变量及内置变量 1. 自定义变量 <properties> <project.build.name& ...
- kettle 合并记录步骤中的 关键字段和 比较字段的说明
该步骤用于将两个不同来源的数据合并,这两个来源的数据分别为旧数据和新数据,该步骤将旧数据和新数据按照指定的关键字匹配.比较.合并. 需要设置的参数: 旧数据来源:旧数据来源的步骤 新数据来源.新数据来 ...
- Windows 10忘记登录密码不用怕,系统U盘/光盘轻松重置
我们有时会遇到忘记Windows10登录密码,或者电脑被其他账户登录后不知道密码无法开机的情况.遇到这些问题后,我们可能会借助一些第三方工具来移除现有密码.然而这些工具本身的安全性还有待检验,肯定不如 ...
- February 2nd, 2018 Week 5th Friday
Reputation takes a life time to build and a second to destroy. 树立名声需要一生的努力,而毁掉它只需要一秒. To be a smart ...
- 个人博客作业Week3(微软必应词典客户端的案例分析)
软件缺陷常常又被叫做Bug,即为计算机软件或程序中存在的某种破坏正常运行能力的问题.错误,或者隐藏的功能缺陷.缺陷的存在会导致软件产品在某种程度上不能满足用户的需要.IEEE729-1983对缺陷有一 ...
- EasyUI DataGrid自适应高度
我的页面分为上下两部分,但发现下面有DataGrid的高度总是自动改,数据根本显示不出来. 后来在博客园里看到这个:http://www.cnblogs.com/xienb/archive/2013/ ...
- Java对XML文件解析方式之一_SAX
SAX(org.xml.sax) Simple API for XML,以事件的形式通知程序,对Xml进行解析. SAX技术的介绍:SAX是一种以事件驱动的XML api,由它定义的事件流可以指定 ...
- EXCEL 偶数、奇数行分开求和公式
例举 : A1行是 123 A2行是 321 A3行是 456 A4行是 789我是加的是A1+A3得出的和还有加的是A2+A4得出的和因为要A1+A3一直加到A601,我用很笨的方式像这样子一个个加 ...
- IntelliJ IDEA2018.3 最新破解方法 无需改host
文章转自 https://blog.csdn.net/SmileLvCha/article/details/78936659 刚把idea升级到最新版,发现要重新激活,网上查了有改host的方法可行, ...
- ssh test
本文以以下需求为背景,介绍详细的做法: 需在同一台服务器同时部署两个不同的 Github 仓库(对 Bitbucket 等 git 服务同样适用) root 用户可在远程登录 SSH 后附上预期的 S ...