zoukankan      html  css  js  c++  java
  • 关于四则运算表达式生成和答案校验的笔记

    软件工程的个人项目是写一个面向小学生的四则运算题目生成和校验工具。主要功能有两个,一是生成四则运算题目,二是对给定的题目和答案,校验其中答案的正确性。

    时间表格


    前期构思的时间比较多,但是在编码和测试中还是花费了不少的时间。

    由于采用的c语言,在字符串的处理和内存管理上花费了较多的时间。

    PSP2.1

    Personal Software Process Stages

    Time

    Planning

    计划

     

      · Estimate

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

     20h

    Development

    开发

     

      · Analysis

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

     6h

      · Design Spec

      · 生成设计文档

     1h

      · Design Review

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

     1h

      · Coding Standard

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

     0.5h

      · Design

      · 具体设计

     2h

      · Coding

      · 具体编码

     7h

      · Code Review

      · 代码复审

     1h

      · Test

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

     4h

    Reporting

    报告

     

      · Test Report

      · 测试报告

     1h

      · Size Measurement

      · 计算工作量

     0.5h

      · Postmortem & Process Improvement Plan

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

     0.5h

     

    合计

     24.5

    题目分析和思路


    主要问题:

    1.算式查重
         非等价去重
         如果两个表达式的数和操作符都一样,我们认为这两个表达式重复。
    2.对大量数据的支持,支持1w个算式,考虑到查重需要顺序检索,使用结构体和链表
    3.答案校对需要支持对中缀表达式的计算
      1)中缀表达式转后缀表达式——调度场算法
      2)后缀表达式的计算
    4.真分数的四则运算(a!=0,b!=0)
         获取操作数:a,b,m,n
         计算结果:k,l(k/l的形式)
         1)加减法:m/a + n/b -> (bm+an)/ab
              乘法:m/a × n/b ->mn/ab
              除法:m/a ÷ n/b ->mb/na(n!=0)
         2)辗转相除法求得最大公约数,化简分数(k/l)
    if(k>l)
        x=gcd(k,l);
    else
        x=gcd(l,k);
    int gcd(int k, int l){
        if(k%l==0)
            return l;
        else
            return gcd(l,k%l);
    }
         另:另记得处理化简之后分母为1的情况
    5.括号问题——生成带括号的算式
         左括号:第一个数/每一个操作符(不含最后一个),若没有生成过左括号,随机一次是否生成左括号。
         右括号:每一个操作符,若生成过左括号没有生成过右括号,随机一次是否生成右括号。
         结尾处:若已经有左括号但是没有右括号,则补上右括号。
         备注:先检测右括号,后检测左括号。
    6.c语言带来的需要注意的问题:c风格式字符串处理,内存管理。
     
    代码中遇到的问题

     1.生成过程中的算式结果合法性检查花费了大量的时间。很多时间花在对生成到一半的表达式进行处理使其成为能够计算的表达式。
     2.处理c风格式字符串与生俱来的麻烦,这点在上一点中也有很大影响。
     3.内存管理问题。为了简化代码,构写了不少函数,传参和返回值基本采用char*类型,释放内存的过程中产生了不少问题。
     
    性能分析

    ArithmeticProducer.exe -r 50 -n 20000

    名称

    非独占样本数

    独占样本数

    非独占样本数百分比

    独占样本数百分比

    -  ArithmeticProducer.exe

    1,159

    624

    100.00

    53.84

    produce

    969

    532

    83.61

    45.90

    _strcmp

    18

    18

    1.55

    1.55

    gcd

    18

    18

    1.55

    1.55

    calc

    152

    16

    13.11

    1.38

    convert

    25

    13

    2.16

    1.12

    transToVulgarFrac

    59

    8

    5.09

    0.69

    getRand

    16

    7

    1.38

    0.60

    getGcd

    22

    4

    1.90

    0.35

    _RTC_CheckEsp

    2

    2

    0.17

    0.17

    getIntResult

    109

    2

    9.40

    0.17

    @ILT+230

    1

    1

    0.09

    0.09

    @ILT+240

    1

    1

    0.09

    0.09

    _RTC_CheckStackVars

    1

    1

    0.09

    0.09

    checkRange

    91

    1

    7.85

    0.09

    __tmainCRTStartup

    1,159

    0

    100.00

    0.00

    main

    1,159

    0

    100.00

    0.00

    mainCRTStartup

    1,159

    0

    100.00

    0.00

    其中produce()是用于生成算式的函数。

    从上述性能分析数据来看,占据CPU时间最多的produce()函数,占比高达45.90%。

    其它函数中,CPU时间主要耗费在计算上(gcd()用于递归计算最大公约数,clac()用于计算后缀表达式的值,convert()用于将中缀表达式转换为后缀表达式以便计算)。

    根据分析数据,produce()函数有很大的优化空间。

  • 相关阅读:
    new delete的内部实现代码
    子串的替换
    求字符串的长度
    TSQL语句学习(四)
    TSQL语句学习(二)
    杭电acm1036
    杭电acm2032
    杭电acm2045
    杭电acm2072
    杭电acm1029
  • 原文地址:https://www.cnblogs.com/dtblog/p/4830876.html
Copyright © 2011-2022 走看看