zoukankan      html  css  js  c++  java
  • 【SE】Week1 : 四则运算题目生成器批改器程序总结

    用户需求详见http://www.cnblogs.com/jiel/p/4810756.html

    1)PSP表格分析(预计耗时):

    PSP2.1

    Personal Software Process Stages

    Time

    Planning

    计划

     

      · Estimate

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

     0.5h

    Development

    开发

     

      · Analysis

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

     1h

      · Design Spec

      · 生成设计文档

     0.5h

      · Design Review

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

     0h

      · Coding Standard

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

     0h

      · Design

      · 具体设计

     1.5h

      · Coding

      · 具体编码

     8h

      · Code Review

      · 代码复审

     2h

      · Test

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

     6h

    Reporting

    报告

     

      · Test Report

      · 测试报告

     0.5h

      · Size Measurement

      · 计算工作量

     0.5h

      · Postmortem & Process Improvement Plan

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

     0.5h

     

    合计

     22h

    2)PSP表格分析(实际耗时):

    PSP2.1

    Personal Software Process Stages

    Time

    Planning

    计划

     

      · Estimate

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

     0.5h

    Development

    开发

     

      · Analysis

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

     0.5h

      · Design Spec

      · 生成设计文档

     0.5h

      · Design Review

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

     0h

      · Coding Standard

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

     0h

      · Design

      · 具体设计

     1h

      · Coding

      · 具体编码

     10h

      · Code Review

      · 代码复审

     2h

      · Test

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

     7h

    Reporting

    报告

     

      · Test Report

      · 测试报告

     0.5h

      · Size Measurement

      · 计算工作量

     0.5h

      · Postmortem & Process Improvement Plan

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

     0.5h

     

    合计

     23h

    3)记录你在改进程序性能上花费了多少时间,描述你改进的思路,并展示一张性能分析的图(由VS2012的性能分析工具自动生成)。如果可能,展示你程序中消耗最大的函数。

    在改进程序性能方面花费的时间包括:最初的算法设计 + coding过程中对想法的qualification + 最后测试过程中的修改 = 0.5h + 6h + 3h = 9.5h

    改进的过程中,花了较多的时间用来修改最初设计的算法:

      采用多步式的结构来存储表达式,取代一般存储整个表达式的做法。

      这样的优点是能更清晰地获得表达式的整体结构和关系信息,比存储整个字符串再做后续分析要简单。

      尤其考虑到需要进行重复性检验,如果将表达式存为字符串将难以判定;相反,按运算步骤存储后,只需比较每步的两个运算元是否构成重复即可。

      在重复性检验环节,优化的一点是存储了两个表达式重复关系的表格,使得后续判断可以不用重复计算。

    【性能分析图】 

    由上可知,最耗时的部分为重复性检验,其代码为:

     1         private static bool isReplicate(int i)
     2         {
     3             for (int k = 0; k < i; k++)
     4                 if (es[i].isReplicate(es[k]))
     5                     return true;
     6             return false;
     7         }
     8 
     9         public bool isReplicate(Expression e) 
    10         {
    11             if (e.numOfOp != this.numOfOp) return false;
    12             if (!e.res[numOfOp - 1].equalTo(res[numOfOp - 1])) return false;
    13             int[] map = new int[numOfOp];
    14             
    15             for (int i = 0; i < numOfOp; i++) {
    16                 bool flag = false;
    17                 for (int j = 0; j < numOfOp; j++)
    18                     if (isomorphic(items[i, 0], items[i, 1], (char)items[i, 2],
    19                         e.items[j, 0], e.items[j, 1], (char)e.items[j, 2], map)) {
    20                         flag = true;
    21                         map[i] = j + 1;
    22                     }
    23                 if (!flag) return false;
    24             }
    25             return true;
    26         }
    27 
    28         private static bool isomorphic(Object t11, Object t12, char op1, 
    29                                        Object t21, Object t22, char op2, int[] map)
    30         {
    31             if (op1 != op2) return false;
    32             if (op1 == '-' || op1 == '/') {
    33                 if (!(t11.GetType().Name.Equals(t21.GetType().Name) &&
    34                       t12.GetType().Name.Equals(t22.GetType().Name)))
    35                     return false;
    36                 if (t11 is Fraction && !((Fraction)t11).equalTo((Fraction)t21))
    37                     return false;
    38                 if (t12 is Fraction && !((Fraction)t12).equalTo((Fraction)t22))
    39                     return false;
    40                 if (t11 is Notation && map[((Notation)t11).getNot() - 1] != ((Notation)t21).getNot())
    41                     return false;
    42                 if (t12 is Notation && map[((Notation)t12).getNot() - 1] != ((Notation)t22).getNot())
    43                     return false;
    44                 return true;
    45             }
    46 
    47             bool flag = true;
    48             if (!(t11.GetType().Name.Equals(t21.GetType().Name) &&
    49                   t12.GetType().Name.Equals(t22.GetType().Name)))
    50                 flag = false;
    51             else {
    52                 if (t11 is Fraction && !((Fraction)t11).equalTo((Fraction)t21))
    53                     flag = false;
    54                 if (t12 is Fraction && !((Fraction)t12).equalTo((Fraction)t22))
    55                     flag = false;
    56                 if (t11 is Notation && map[((Notation)t11).getNot() - 1] != ((Notation)t21).getNot())
    57                     flag = false;
    58                 if (t12 is Notation && map[((Notation)t12).getNot() - 1] != ((Notation)t22).getNot())
    59                     flag = false;
    60             }
    61             if (flag) return true;
    62             
    63             if (!(t11.GetType().Name.Equals(t22.GetType().Name) &&
    64                   t12.GetType().Name.Equals(t21.GetType().Name)))
    65                 return false;
    66             if (t11 is Fraction && !((Fraction)t11).equalTo((Fraction)t22))
    67                 return false;
    68             if (t12 is Fraction && !((Fraction)t12).equalTo((Fraction)t21))
    69                 return false;
    70             if (t11 is Notation && map[((Notation)t11).getNot() - 1] != ((Notation)t22).getNot())
    71                 return false;
    72             if (t12 is Notation && map[((Notation)t12).getNot() - 1] != ((Notation)t21).getNot())
    73                 return false;
    74             return true;
    75         }

    4)共享你对程序进行测试的至少10个测试用例,以及说明为什么你能确定你的程序是正确的。(不正确的程序得0分,不管性能如何)

    在测试环节,我用的方法简单但有效,

    对功能一:题目生成 进行测试时,生成了60000+个,bound = 3(即所有数字必须小于3)的表达式,具体内容在工程文件中,在此由于篇幅限制只共享几个:

    1. 0 × 2'1/2 =
    2. 1/2 ÷ 2 =
    3. 1'1/2 + 0 =
    4. 1 ÷ 1/2 =
    5. 1'1/2 ÷ 1'1/2 × 1'1/2 =
    6. 2 ÷ (1'1/2 × (1 + 2'1/2)) =
    7. 2'1/2 + 1 + 2'1/2 =
    8. 2 ÷ (1/2 × (1'1/2 ÷ 2'1/2)) =
    9. 2'1/2 ÷ 2 =
    10. 1 + 2'1/2 =
    11. 1'1/2 - (2'1/2 - 2) =
    12. 1 + 0 =
    13. 2 × 0 =
    14. 1/2 ÷ (1/2 + 1) =
    15. 2'1/2 - (1/2 + 1/2) =
    16. 1'1/2 + 1/2 =
    17. 1'1/2 × 2 + (2 - 2) =
    18. 1 ÷ 2 =
    19. 2 × 2'1/2 =
    20. 0 ÷ ((1/2 - 0) × 1) =
    21. 0 × (0 ÷ 1) =
    22. 1 + (2'1/2 + 1/2) =
    23. 2'1/2 × (2 × 2'1/2) =
    24. 1 × 1/2 =
    25. 2'1/2 - (1/2 × (1/2 + 2'1/2)) =
    26. 1'1/2 ÷ 1 × 1/2 ÷ 1'1/2 =
    27. 1'1/2 - 0 =
    28. (2 + 1'1/2) × (2'1/2 × 2'1/2) =
    29. 1'1/2 + 1'1/2 =
    30. 1 × 1/2 ÷ 2'1/2 =
    31. 2 ÷ (1'1/2 × 1 + 1/2) =
    32. 1 ÷ (1/2 × (1'1/2 - 1)) =
    33. (2 × 0 - 0) ÷ 1 =
    34. 2 + 1 =
    35. 2 ÷ (1 × 2'1/2) =
    36. 1 ÷ (2'1/2 × 1) =
    37. 1/2 + 2'1/2 + (1/2 + 0) =
    38. 1/2 × (0 - 0) =
    39. 1/2 ÷ 1 ÷ (2'1/2 + 1'1/2) =
    40. 1'1/2 + (2 × 0) =
    41. 1 + (2 ÷ (2 ÷ 2'1/2)) =
    42. 2'1/2 ÷ 1 =
    43. 2'1/2 × 2'1/2 =
    44. 1/2 ÷ (2 + 1'1/2) =
    45. 0 ÷ 1'1/2 =
    46. 2'1/2 × 1/2 =
    47. 1 × (2'1/2 × 1'1/2) =
    48. 1 + (1'1/2 × 0) =
    49. 1 + 1/2 - 1/2 =
    50. 2 + 2 =

    在对功能二:评分系统 的测试中,我利用了功能一生成的10000个测试样例作为题目,结合程序生成的结果,将其直接作为答案,输入程序。

    最终得到的结果是Correct: 10000 Wrong: 0(和输入表达式数目一致)。

    5)说明你在个人项目中学到了什么。

      在此次的个人项目中,学到的最大一点即对项目的规划和设计远比实际写代码要重要。没有一个清晰,细化到每一个流程的设计会大大增加工程的完成时间。在此次的项目中,由于在设计环节仅仅是提出了分步存储的这么一个概念,但对实际实现并没有进行较好的规划,导致在真正开始写代码时走了不少弯路,代码耗时比预期要长,并且后期的优化问题也不断,大大降低了效率。

      综合这次实践,在下次的工程中,需要对所做的东西有个清晰细致的规划,不能只停留在概念层面。

  • 相关阅读:
    关于题目中的内存限制
    手动实现最小堆和最大堆(优先队列)
    线性筛素数(欧拉筛)+前缀和优化
    并查集
    快速排序

    字典按中文姓名排序
    oc程序代码
    学生字典计算年龄差 随机50个数
    nsset
  • 原文地址:https://www.cnblogs.com/kanelim/p/4830792.html
Copyright © 2011-2022 走看看