zoukankan      html  css  js  c++  java
  • 2016012020+小学四则运算练习软件项目报告

    coding.net源码仓库地址:https://git.coding.net/day_light/szysmaster1.git

    一、需求分析

        (一)题目:尝试按照《构建之法》第2章中2.3所述PSP流程,使用JAVA编程语言,独立完成一个3到5个运算符的四则运算练习的命令行软件  开发。软件基本功能要求如下:

    • 程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。
    • 为了让小学生得到充分锻炼,每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3÷5+2=2.6,2-5+10=7等算式。
    • 练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
    • 当程序接收的参数为4时,以下为一个输出文件示例。
          2018010203
          13+17-1=29
          11*15-5=160
          3+10+4-16=1
          15÷5+3-2=4

      软件附加功能要求如下:支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号必须大于2个,且不得超过运算符的个数。(5分)扩展程序功能支持真分数的出题与运算(只需要涵盖加减法即可),例如:1/6 + 1/8 + 2/3= 23/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6,且计算过程中与结果都须为真分数。(5分)

    (二)分析

    1.使用random()产生3~5个随机数来做运算符,即产生4~6个随机数来做运算数。

    2.由于小学生运算不能产生负数、整数且除数不能为0,解决方案:当出现上述情况时,重新产生随机数。

    3.运算结果的计算实现:边产生随机数边计算,不断更新sum。

    4.支持括号运算。

    5.部分真分数

    6.利用IO输出流将学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中。        

    二、功能设计

         (一)基本功能:随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间

         (二)扩展功能:支持括号运算、真分数运算

    三、设计实现:设计包括你会有哪些类,这些类分别负责什么功能,他们之间的关系怎样?你会设计哪些重要的函数,关键的函数是否需要画出流程图?函数之间的逻辑关系如何?

     (一)共包含两个类文件,Main为主函数,负责输出到result.txt文件;Lib是辅助类,compute是支持带括号的整数加减乘除运算,fraction是负责真分数加减运算;max求最大公约数。

     (二)调用关系如图所示

    四、算法详解

    (一)主函数

     1 public class Main {
     2     public static void main(String[] args) {
     3         int n = 0 ;
     4         try 
     5         {
     6             n=Integer.parseInt(args[0]);
     7         }
     8         catch (Exception e) 
     9         {
    10             System.out.println("非法字符,请输入1~1000内的整数:");
    11         }
    12         try {
    13             PrintStream ps = new PrintStream("../result.txt");
    14             System.setOut(ps);
    15         }catch(Exception e) {
    16             System.out.println("文件创建失败!");
    17         }
    18         System.out.println("2016012020");
    19         Lib.compute(n);//整数运算
    20         Lib.fraction(n);//真分数运算    
    21     }
    22 }

    (二)整数计算使用边生成,边计算的方式,每一次运算均更新sum并输出arr1 = "" + oper[s1] + "" + b1;以下为核心代码,完整代码见coding.net

     1 for (int i = 1; i < th; i++) {
     2 
     3                 int s1 = random.nextInt(5);
     4                 int b1 = random.nextInt(100);
     5                 a = sum;  //更新sum
     6                 if (oper[s1] == ' ') {
     7                     s1++;
     8                 }
     9                 if (oper[s1] == '-') {
    10                     while (a - b1 < 0) {
    11                         b1 = random.nextInt(100);
    12                     }
    13                     sum = a - b1;
    14                 }
    15                 if (oper[s1] == '/') {
    16                     if (b1 == 0)
    17                         b1++;
    18                     while (a % b1 != 0) {
    19                         b1 = random.nextInt(99) + 1;
    20                     }
    21                     sum = a / b1;
    22                 }
    23                 if (oper[s1] == '+')
    24                     sum = a + b1;
    25                 if (oper[s1] == '*')
    26                     sum = a * b1;
    27                 String arr1 = "";
    28                 arr1 = "" + oper[s1] + "" + b1;

    (三)使用fraction类方法实现真分数出题实现:生成四个随机数,分别表示分子、分母;当分子大于分母时(即假分数出现时),交换分子分母,当分子分母有公因数时,调用max方法实现化简,当中间的计算结果出现假分数时,重新出题。

     

     1 //真分数运算
     2     static public void fraction(int n) { // a为分子1,b为分子2
     3         for (int j = 0; j < n; j++) {
     4             Random rand = new Random();
     5             int a = rand.nextInt(10) + 1;
     6             int Fm1 = rand.nextInt(10) + 1;// 分母1
     7             if (a > Fm1) {
     8                 int t = a;
     9                 a = Fm1;
    10                 Fm1 = t;
    11             }
    12             char[] oper = { '+', '-' };
    13             int s = rand.nextInt(2);
    14             int b = rand.nextInt(10) + 1;
    15             int Fm2 = rand.nextInt(10) + 1;// 分母2
    16             if (b > Fm2) {
    17                 int t = b;
    18                 b = Fm2;
    19                 Fm2 = t;
    20             } // 化简
    21             int ha = a / max(a, Fm1);
    22             int hFm1 = Fm1 / max(a, Fm1);
    23             int hb = b / max(b, Fm2);
    24             int hFm2 = Fm2 / max(b, Fm2);
    25             if (oper[s] == '+') {
    26                 a = a * Fm2 + b * Fm1;
    27                 int F = Fm1 * Fm2;
    28                 if (a > F) {
    29                     a = rand.nextInt(6) + 1;
    30                     Fm1 = rand.nextInt(6) + 1;// 分母1
    31                 }
    32                 a = a / max(a, F);
    33                 Fm1 = F / max(a, F);
    34             }
    35             if (oper[s] == '-') {
    36                 a = a * Fm2 - b * Fm1;
    37                 int F = Fm1 * Fm2;
    38                 if (a > F || a < 0) {
    39                     a = rand.nextInt(10) + 1;
    40                     Fm1 = rand.nextInt(10) + 1;// 分母1
    41                 }
    42                 a = a / max(a, F);
    43                 Fm1 = F / max(a, F);
    44             }
    45             System.out.print(ha + "/" + hFm1 + oper[s] + b + "/" + Fm2);
    46             int th = (int) (Math.random() * 2) + 3;// 3~5个运算符
    47             for (int i = 1; i < th; i++) {
    48                 Random random = new Random();
    49                 int s1 = random.nextInt(2);
    50                 int b1 = random.nextInt(10) + 1;
    51                 int Fmt = random.nextInt(10) + 1;// 分母2
    52                 if (a > Fm1) {
    53                     int t = a;
    54                     a = Fm1;
    55                     Fm1 = t;
    56                 }
    57                 if (b1 > Fmt) {
    58                     int t = b1;
    59                     b1 = Fmt;
    60                     Fmt = t;
    61                 } // 化简
    62                 int a1 = a / max(a, Fm1);
    63                 int Fm11 = Fm1 / max(a, Fm1);
    64                 int hb1 = b1 / max(b1, Fmt);
    65                 int hFmt = Fmt/ max(b1, Fmt);
    66                 if (oper[s1] == '+') {
    67 
    68                     a = a * Fmt + b * Fm1;
    69                     int F = Fm1 * Fmt;
    70 
    71                     if (a > F) {
    72                         a = rand.nextInt(10) + 1;
    73                         Fm1 = rand.nextInt(10) + 1;// 分母1
    74                     }
    75                     a = a / max(a, F);
    76                     Fm1 = F / max(a, F);
    77                 }
    78                 if (oper[s1] == '-') {
    79 
    80                     a = a * Fmt - b * Fm1;
    81                     int F = Fm1 * Fmt;
    82                     if (a > F || a < 0) {
    83                         a = rand.nextInt(10) + 1;
    84                         Fm1 = rand.nextInt(10) + 1;// 分母1
    85                     }
    86                     a = a / max(a, F);
    87                     Fm1 = F / max(a, F);
    88                 }
    89                 String arr1 = "";
    90                 if (a < Fm1 && a >= 0) {
    91                     arr1 = oper[s1] + "" + hb1 + "/" + hFmt;
    92                     System.out.print(arr1);
    93                 }
    94             }
    95             System.out.println("=");
    96             // System.out.println("=" + a + "/" + Fm1);
    97         }
    98     }

     

    五、测试运行

      (一)命令行测试:

            

        (二)输出到result.txt文件

                

    (三)生成文件位置

    六、比较独特的的代码片段

      括号优先级的判定

     1      char[] oper = { '+', '-', ' ', '*', '/' };
     2                 if (i == 1) {
     3                     k = s;
     4                     if (s1 - k >= 2) {
     5                         System.out.print(")" + arr1);
     6                     } else {
     7                         System.out.print(arr1);
     8                     }
     9                 }
    10 
    11                 if (i != 1) {
    12                     if (s1 - k >= 2) {
    13                         System.out.print(")" + arr1);
    14                     } else {
    15                         System.out.print(arr1);
    16                     }
    17                     k = s1;
    18                 }

    七、总结:你设计的程序如何实现软件设计的'模块化'原则。

            1.整个项目分为两个源文件,Main和Lib辅助类,实现了整体的模块化。

            2.在Lib辅助类中调用了fractoin和caculate方法,在fraction方法中使用了max函数,求最大公约数,实现了辅助类里的模块化。

    采用模块化编程,方便调试,当运行报错时,可以分别测试每一个模块;还有利于移植,当编程时需要实现相同或相似的功能,可以只做小部分改动,减小了代码的冗余度。

    八、展示PSP

     

    任务内容

    计划共完成需要的时间(min)

    实际完成需要的时间(min)

    Planning

    计划

    8

    6

    ·        Estimate

    ·   估计这个任务需要多少时间,并规划大致工作步骤

    3天

    4天

    Development

    开发

    82

    88

    ·        Analysis

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

    30

    45

    ·        Design Spec

    ·         生成设计文档

    5

    8

    ·        Design Review

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

    4

    6

    ·        Coding Standard

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

    10

    15

    ·        Design

    ·         具体设计

    10

    30

    ·        Coding

    ·         具体编码

    180

    240

    ·        Code Review

    ·         代码复审

    8

    20

    ·        Test

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

    60

    120

    Reporting

    报告

    9

    6

    ·         Test Report

    ·         测试报告

    3

    2

    ·         Size Measurement

    ·         计算工作量

    2

    1

    ·         Postmortem & Process Improvement Plan

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

    10

    10

    九、总结

        因为之前没有进行过单元测试,所以总结了自己在进行单元测试时遇到的问题。

     (一)找不到或无法加载主类

      查阅网上资料出现此种情况,有两类原因:

      1.环境配置

      (1)检验方法:输出java、javac、java -version

      2.在你在eclipse写的时候里面会有package,把它删掉就可以了(我属于这种情况)

       PS:同时要注意编译的java源文件有没有包含Main函数

     (二)当源文件不止一个时,所有源文件要一起编译,即javac *.java

    十、反思与不足 

      在编程时有时会为了加快编程进度,使用的方法不够简洁高级,忽略了代码的质量,导致后期功能扩展时很困难,有时觉得自己省了时间,实际上到了要实现后期功能时举步维艰,反而延长了整体编程的时间。

       在扩展功能上,实现了”)“而非”()“;未能成功输出真分数的计算结果。

    十一、参考博客

    【1】初学者利用git 上传代码到Coding的简单操作步骤

    【2】错误提示:fatal: remote origin already exists.

    【3】解决提交到github报错Please tell me who you are

    【4】coding.net使用指南

  • 相关阅读:
    XML应用程开发--下
    XML应用程序开发--上
    TCP通信客户端简单示例
    TCP网络通信服务器端简单示例
    XML基本内容学习笔记
    如何在Qt的widget上右键显示菜单
    关于双指针遍历
    常见的四种排序算法
    JAVA Class13
    JAVA练习
  • 原文地址:https://www.cnblogs.com/13-14/p/8621405.html
Copyright © 2011-2022 走看看