四则运算(java) 王哲文 邹庭和

github地址:https://github.com/3116004655/simple-calculator/tree/master

 

一、题目:实现一个自动生成小学四则运算题目的命令行程序

功能:

1. 使用 -n 参数控制生成题目的个数,例如

Myapp.exe -n 10,将生成10个题目。【已实现】

2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如

Myapp.exe -r 10,将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。【已实现】

3. 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 − e2的子表达式,那么e1 ≥ e2。【减法未实现】

4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。【已实现】

5. 每道题目中出现的运算符个数不超过3个。【已实现】

6. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+×左右的算术表达式变换为同一道题目

生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:

1. 四则运算题目1

2. 四则运算题目2

……

其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。【检测重复部分未实现】

7. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:

1. 答案1

2. 答案2

特别的,真分数的运算如下例所示:1/6 + 1/8 = 7/24。【已实现】

8. 程序应能支持一万道题目的生成。【已实现】

9. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。【未实现】

 

二、设计实现

1. 数值生成

题目要求生成的数要带上分数,设计方面是通过随机产生分子和分母的整数值两数相除,然后进行有关分数方面的操作,例如约分,假分数化为带分数和分数之间运算等操作,最后转化为字符输出。这些方法用一个分数类Fraction()来保存。

 

2. 算术表达式生成

题目要求不超过三个运算符,所设计时则通过生成一个随机数,然后进行循环随机数运算,通过另生成一个随机数进行switch选择生成随机运算符且再生成一个随机数控制运算符个数随机,每次循环用字符保存,从而循环生成一个字符算式,再用一个字符数组循环保存每个算式,最后再进行输出。其中,用num、max分别控制生成的算式题目数及数值范围,以达到控制题目目的。

 

三、用户使用说明

举例:

-n   [数值]     使用 -n 参数控制生成题目的个数。

-r   [数值]     使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围。

 

四、关键代码

1. 分数生成

 1 package arithmetic;
 2 /**
 3  *
 4  * @author Administrator
 5  */
 6 
 7 public class Fraction {
 8     private int a; //分子
 9     private int b; //分母
10     
11      public Fraction(String string) { 
12         string = string.trim();
13         int char1 = string.indexOf("'"); 
14         int char2 = string.indexOf("/"); 
15        if (char1 != -1) { // 数字为带分数
16             int z = Integer.valueOf(string.substring(0, char1));
17             b = Integer.valueOf(string.substring(char2 + 1));
18             a = z * b + Integer.valueOf(string.substring(char1 + 1, d));
19         } else if (char2 != -1) { // 数字为真分数
20             b = Integer.valueOf(string.substring(char2 + 1));
21             a = Integer.valueOf(string.substring(0,char2));
22         } else { // 数字为整数
23             a = Integer.valueOf(string);
24             b = 1;
25         }
26         build(a, b);
27     }
28     public Fraction(int a, int b) {
29         build(a, b);
30     }
31 
32     // 数字形式转换为字符串形式
33     public String toString() {
34         if (b == 1) {
35             return String.valueOf(a);
36         } else {
37             int i = a / b;
38             if (i != 0) {
39                 return String.format("%d'%d/%d", i, a - b * i, b);
40             } else {
41                 return String.format("%d/%d", a, b);
42             }
43         }
44     }
45 
46     // 给定分子分母构造分数
47     private void build(int a, int b) {
48         if (b == 0) {
49             throw new RuntimeException("分母不能为0");
50         }
51         int c = comfactor(a, b);
52         this.a = a / c;
53         this.b = b / c;
54     }
55 
56     // 公约数
57     private int comfactor(int a, int b) {
58         int mod = a % b;
59         return mod == 0 ? b : comfactor(b, mod);
60     }
61 
62     //  a + b
63     public Fraction add(Fraction fraction) {
64         return new Fraction(this.a * fraction.b + fraction.a * this.b, this.b * fraction.b);
65     }
66 
67     // a - b
68     public Fraction subtraction(Fraction fraction) {
69         return new Fraction(this.a * fraction.b - fraction.a * this.b, this.b * fraction.b);
70     }
71 
72     // = a x b
73     public Fraction multiplication(Fraction fraction) {
74         return new Fraction(this.a * fraction.a, this.b * fraction.b);
75     }
76 
77     // a/b
78     public Fraction division(Fraction fraction) {
79         return new Fraction(this.a * fraction.b, b * fraction.a);
80     }
81 
82     public double getDouble() {
83         return a / b;
84     }
85 
86 }

 

2. 表达式生成及计算(仅显示带分数部分)

 

  1 package arithmetic;
  2 
  3 import java.util.Random;
  4 
  5 import javax.script.ScriptEngine;
  6 import javax.script.ScriptEngineManager;
  7 import javax.script.ScriptException;
  8 
  9 
 10 //带真分数四则运算
 11 public class createQuestion1 {
 12     public void testQuestion(String num,String max) {
 13          fileUnit fileunit=new fileUnit();
 14          int num1=Integer.parseInt(num);
 15          int max1=Integer.parseInt(max);
 16          String result=null;
 17          String operator1=null;
 18          String txt=null;
 19          String txt1=null;
 20          int operator,operatorNum;
 21          //int[] a=new int[10000];
 22          Fraction [] arr=new Fraction[10000];
 23          Fraction [] arr1=new Fraction[4];
 24          String [] Result = new String [10000];
 25          System.out.println("生成的带真分数四则运算试题为:");
 26          
 27          for(int j=1;j<=num1;j++) {
 28          //a[0]=(int)(Math.random()*max1);
 29          //result=a[0]+"";
 30           result=null;
 31              Random c = new Random();
 32           Random d = new Random();
 33           Fraction e = new Fraction(c.nextInt(max1)+1,d.nextInt(max1)+1);
 34           arr1[0]=e;
 35          operatorNum=(int)(Math.random()*max1%4);
 36          while(operatorNum==0) {
 37              operatorNum=(int)(Math.random()*max1%4);
 38          }
 39          for(int i=1;i<operatorNum+1;i++)
 40          {
 41         // a[i]=(int)(Math.random()*max1);
 42          Fraction b = new Fraction(c.nextInt(max1)+1,d.nextInt(max1)+1);
 43          operator=(int)(Math.random()*max1%4);
 44          switch(operator) {
 45          case 0:operator1="+";arr1[i]=arr1[i-1].add(b);break;
 46          case 1:operator1="-";arr1[i]=arr1[i-1].subtraction(b);break;
 47          case 2:operator1="*";arr1[i]=arr1[i-1].multiplication(b);break;
 48          case 3:operator1="/";arr1[i]=arr1[i-1].division(b);break;
 49          }
 50          if(i==1) {
 51              result="("+e+")"+operator1+"("+b+")"+"";
 52          }
 53          else {
 54              result="("+result+")"+operator1+"("+b+")"+"";
 55          } 
 56          } 
 57          arr[j]=arr1[operatorNum];
 58          System.out.println("题目"+j+":"+"result="+result);  
 59          if(txt==null) {
 60              txt="result="+result+"\n";
 61          }
 62          else {
 63              txt=txt+"result="+result+"\n";
 64          }
 65          Result[j]=arr[j]+"";
 66          if(txt1==null) {
 67              txt1="result="+Result[j]+"\n";
 68          }
 69          else {
 70              txt1=txt1+"result="+Result[j]+"\n";
 71          }
 72          }  //下面注释部分因为没有考虑优先级而出现错误,未实现。
 73          /*
 74          ScriptEngineManager manager = new ScriptEngineManager();
 75          ScriptEngine engine = manager.getEngineByName("js");//可以通过这个来调用JS模块的函数
 76          for(int k=1;k<=num1;k++) {
 77          Object result2;
 78         try {
 79             result2 = engine.eval(Result[k]);
 80              if(txt1==null) {
 81                  txt1="result="+result2+"\n";
 82              }
 83              else {
 84                  txt1=txt1+"result="+result2+"\n";
 85              }
 86             
 87         } catch (ScriptException e) {
 88             // TODO Auto-generated catch block
 89             e.printStackTrace();
 90         }
 91         }
 92          */
 93          String fileName="c:\\Exercises.txt";
 94          System.out.println("练习题目已生成,存储路径为:"+fileName);
 95          fileunit.WriteTextFile(fileName,"题目"+"\n");
 96          fileunit.WriteTextFile(fileName, txt);
 97          String fileName1="c:\\Answers.txt";
 98          System.out.println("练习题目答案已生成,存储路径为:"+fileName1);
 99          fileunit.WriteTextFile(fileName1,"答案"+"\n");
100          fileunit.WriteTextFile(fileName1, txt1);     
101          
102 }
103 }

 

 

五、测试运行结果截图

结果出来的时候有些bug,上面有说明。

 

 

 

 

 

五、PSP

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 35

45 

· Estimate

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

 35

45 

Development

开发

 930

 1290

· Analysis

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

70 

 120

· Design Spec

· 生成设计文档

 25

25 

· Design Review

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

 40

80 

· Coding Standard

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

 25

25 

· Design

· 具体设计

 70

110 

· Coding

· 具体编码

 600

780 

· Code Review

· 代码复审

 50

50 

· Test

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

 50

100 

Reporting

报告

 90

90

· Test Report

· 测试报告

 25

25 

· Size Measurement

· 计算工作量

 15

15 

· Postmortem & Process Improvement Plan

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

50 

50 

合计

 

 1055

 1425

 

六、经验小结

        这次四则运算作业做的并不成功,基本功能部分已实现,有些关键部分没有实现。主要原因是没有做好充分的准备和思考不够周到。在计算结果的时候直接用循环去做,导致了没有考虑运算符号的优先级,直接从左往右进行运算,所以得出了错误的结果。检测出错误之后,虽然考虑到了用栈的方式去计算结果,但是因为要花费很长时间研究而且没有充分准备,所以没时间修改。

      邹庭和主要负责算数表达式的生成和计算,我主要负责数值中分数的设定和生成,通过这次编程我体会到了这次的编程要用到以前学的知识,例如数据结构,数据结构主要内容是关于数据的不同存储方式,应用很广泛。这次因为最后才想到数据结构的栈,导致准备并不充分,最后结果出现了错误。

     经过反思之后,我们意识到“never stop coding”的重要性,平常代码还是要练的,以前的知识还是要回顾一下的,希望在以后的编程中能再提高自己。

 

posted @ 2018-09-30 15:41  休眠中的熊  阅读(190)  评论(0编辑  收藏  举报