zoukankan      html  css  js  c++  java
  • 四则运算生成器

    本次个人项目为实现一个随机生成四则运算算式的程序,同时提供检查答案的功能。整个项目的情况如下。

    一、总体项目PSP表格

    PSP2.1

    Personal Software Process Stages

    Time

    Planning

    计划

    8小时

      · Estimate

      · 估计这个任务需要多少时间

    8小时 

    Development

    开发

    15小时20分钟 

      · Analysis

      · 需求分析 (包括学习新技术)

    40分钟

      · Design Spec

      · 生成设计文档

    30分钟 

      · Design Review

      · 设计复审 (和同事审核设计文档)

    0

      · Coding Standard

      · 代码规范 (为目前的开发制定合适的规范)

    10分钟

      · Design

      · 具体设计

    1小时

      · Coding

      · 具体编码

    6小时

      · Code Review

      · 代码复审

    0

      · Test

      · 测试(自我测试,修改代码,提交修改)

    8小时

    Reporting

    报告

     

      · Test Report

      · 测试报告

    0

      · Size Measurement

      · 计算工作量

    30分钟

      · Postmortem & Process Improvement Plan

      · 事后总结并提出过程改进计划

    30分钟

     

    合计

    17小时20分钟

    代码实现过程中,由于对设计复审、代码复审以及测试报告的具体作用的不理解,未能进行这几个过程。

    二、需求分析

    这里仿照《一线架构师实践指南》中给出的ADMEMS矩阵(需求层次——需求方面矩阵)方法对个人项目进行需求分析。由于这里没有运维等业务级需求,因此将原方法进行了简化。在此,我将原题目中的需求划分为了用户级和开发级。其中,用户级需求是从用户角度看,满足所需要实现的种种功能。而开发级需求则是在开发的过程中,我们所需要考虑的开发层面的问题。同时,我们将每一级的需求划分为三类,功能性需求、质量要求以及约束条件。

    将原题目中给出的所有需求按照这些分类整理在下面的表格中。我们可以根据用户的“支持10000道题目生成”进一步推出一个原需求中未提及的开发质量需求:整个程序的算法复杂度在O(n)到O(nlogn)左右,否则无法在相对合理的时间内生成一万道题目。

      功能 质量 约束
    用户级需求

    命令行参数输入出题数、数据范围

    自动生成四则运算,支持整数和真分数

    支持括号

    题目存入Exercises.txt中

    同时生成题目答案,存入Answers.txt中

    可以判断答案对错

    支持一万道题目的生成

    用户输入有误时程序不崩溃

    错误输入时需输出帮助信息

    生成的算式需满足:

      减法计算无负数

      除法计算结果为真分数

      运算符不超过3个

      +和*交换不重复

    真分数五分之三表示为3/5

    真分数二又八分之三表示为2’3/8

    Exercises.txt文件格式如下:

    1. 四则运算题目1

    2. 四则运算题目2

    ……

    Answers.txt文件格式如下:

    1. 答案1

    2. 答案2

    判卷结果输出到文件Grade.txt,格式如下:

    Correct: 5 (1, 3, 5, 7, 9)

    Wrong: 5 (2, 4, 6, 8, 10)

    开发级需求

    写出至少10个测试用例确保你的程序能够正确处理各种情况。

    算法复杂度在O(n)到O(nlogn)左右

    经过Code Quality Analysis工具的分析并消除所有的警告

    采用C++或者C#语言实现,可以使用.Net Framework

    运行环境为32-bit Windows 78

    三、项目设计

    (1) 概要设计

    分数类:用于处理分数之间的计算以及输入输出,是整个程序中数的最基本单位。

     1 class Fraction
     2 {
     3 public:
     4     Fraction(); 5     Fraction(const Integer& a, const Integer& b = 1);
     6     ~Fraction(void);
     7 
     8     Fraction operator + (const Fraction&) const;
     9     Fraction operator - (const Fraction&) const;
    10     Fraction operator * (const Fraction&) const;
    11     Fraction operator / (const Fraction&) const;
    12 
    13     bool operator > (const Fraction&) const;
    14     bool operator < (const Fraction&) const;
    15     bool operator == (const Fraction&) const;
    16 
    17     bool valid();18     Integer getNumerator() const;19     Integer getDenominator() const;20 
    21     friend std::wostream& operator << (std::wostream& out, const Fraction& frac);
    22     friend std::wistream& operator >> (std::wistream& in, Fraction& frac);
    23 };
    24     

    算式类:在分数类的基础上,提供和算式相关的功能,包括输入输出计算答案,比较两个算式是否相等。

     1 class Equation
     2 {
     3 public:
     4     Equation(); 5     Equation(const Equation& eq);
     6     Equation(Fraction *n); 7     Equation(Equation* l, Equation* r, wchar_t flag);
     8     ~Equation(void);
     9 
    10     const Fraction& getAns() const;11     bool valid();12 
    13     bool operator == (const Equation& eq) const;
    14     friend std::wostream& operator << (std::wostream& out, const Equation& eq);
    15     friend std::wistream& operator >> (std::wistream& in, Equation& eq);
    16 };

    用户界面模块:解析命令行参数输入,负责与用户相关的交互等。

    随机出题模块:负责不重复地生成一定数量的题目。

    (2)具体设计

    在上述的设计中,Equation类的内部需要单独进行一些设计。因为,其涉及到如何判断两个等式是否相等、如何计算答案的问题。

    经过思考,我最终采用了树状结构来表示整个表达式。我按照计算顺序将其构建为一棵树,其中每个叶节点为算式中的数,而内部节点为符号。

    四、测试用例

    (1)整体测试

    case 1:

    直接运行Myapp.exe,测试无参数状态下能否正常输出提示。

    case 2:

    Myapp.exe -n 10,测试无-r是否输出提示。

    case 3:

    Myapp.exe -n -1 -r 10

    Myapp.exe -n 10 -r -1 

    Myapp.exe -n 2t -r 10

    Myapp.exe -n 10 -r ttt

    测试-n和-r参数有误时能否正确输出提示。

    case 4:

    Myapp.exe -n 10 -r 10

    测试正确输入下,能否按照需求正确生成不重复的式子。

    case 5:

    Myapp.exe -n 10000 -r 10

    测试正确的大数据量输入下,能否按照需求正确生成不重复的式子。

    case 6:

    Myapp.exe -e Exercises.txt -a Answers.txt

    测试正确输入下能否正确进行判卷工作。

    case 7:

    修改之前的Answer.txt,将部分答案改成错误的。

    Myapp.exe -e Exercises.txt -a Answers.txt

    测试正确输入下能否正确进行判卷工作。

    case 8:

    修改之前的Answers.txt,将部分答案改成错误的格式。

    Myapp.exe -e Exercises.txt -a Answers.txt

    测试错误输入下能否正确输出相应的提示。

    case 9:

    生成10000个的同时进行要求程序判断Exercises.txt和Answers.txt中的答案是否正确。

    Myapp.exe -n 10000 -r 10 -e Exercises.txt -a Answers.txt

    多次运行,确保每次的Grade.txt中的结果均为正确10000道。

    (2)单元测试

    在开发的过程中,我首先进行了单元测试,以保证关键模块的正确性。

    对于Fraction类,我进行了以下几组测试:

    1. 检验构造函数及化简是否正确,比对(i*j)/j和i是否相等(i,j在1-100之间枚举),若相等则说明Fraction的构造函数及相关的自动化简等功能正确。
    2. 枚举所有i/j,其中i,j在100的范围内,将该分数写入到文件,再从文件读出,若二者相等,则说明Fraction类对于输入输出流的重载正确。
    3. 测试文件中的数据若是格式错误的,能否正确设置流的badbit。

    对于Equation类,我进行了以下几组测试:

    1. 测试Equation类相等的实现是否正确。采用了老师在个人项目的描述中所使用的几个例子。
    2. 同Fraction类一样,测试了输入输出流相关重载是否正确。(共选用了4组较为具有代表性的用例)

    由于这两个类十分核心,因此,这两个类的单元测试通过,基本可以确保程序整体上是正确的。

    根据VS给出的代码覆盖率分析,我进行的测试可以覆盖70%以上的代码,余下的部分主要是拷贝构造函数、getter/setter、分数的四则运算等极其不易出错的短代码。

    而位于核心部分的输入输出流的解析等都覆盖得相对较为完整。

     五、性能分析及改进

    整个程序常调用的一个路径是维护分数的最简的代码。同时VS的分析也指出了,去重部分占据了相当大的一段时间。我的去重是采用set完成的。set内部的红黑树也许是一个值得改进的地方。

    红黑树的算法复杂度相较于哈希表较高,可以采用C++11标准中的unordered_set代替set,以改进性能。

  • 相关阅读:
    多级导航Menu的CSS
    Centos7在线安装PostgreSQL和PostGIS
    PostGis 根据经纬度查询两点之间距离
    在PowerDesigner中表显示中添加Code的显示
    Tomcat部署Geoserver
    PostGIS之路AddGeometryColumn函数添加一个几何类型字段
    怎样把多个excel文件合并成一个
    Error:java: 无效的目标发行版: 11
    PowerDesigner导出Excel
    GeoServer发布高清电子地图
  • 原文地址:https://www.cnblogs.com/fzyz999/p/4822324.html
Copyright © 2011-2022 走看看