小学生四则运算练习项目报告

时间:2023-02-13 14:12:09

github地址:https://github.com/myGitHub1018/Student_comput

一、需求分析

     1、由用户输入参数n,然后随机产生n道加减乘除练习题;

     2、每个数字在 0 和 100 之间,运算符在3个到5个之间;

     3、运算过程中不得出现负数与非整数,比如不能出 3/5+2=2.6,2-5+10=7等算式;

     4、将学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt中,文件目录与程序目录一致。

      例如:当程序接收的参数为4时,输出如下:

小学生四则运算练习项目报告

      软件附加功能要求如下:

  • 支持有括号的运算式,包括出题与求解正确答案。算式中存在的括号必须大于2个,且不得超过运算符的个数。
  • 扩展程序功能支持真分数的出题与运算,例如:1/6 + 1/8 + 2/323/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6。

二、设计实现

      1、由用户输入参数n,保存练习题的数量;

      2、当输入不合理时,提示重新输入;

      3、随机产生3-5个加减乘除运算符以及1-100之间的随机数;

      4、运算结果不能为负数和非整数;

      5、将学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt中。

三、功能实现

      程序流程图:

小学生四则运算练习项目报告

四、测试运行

      1、项目名称为Suanfa_l,路径如下(包括result.txt文件):

小学生四则运算练习项目报告

      2、测试异常输入:

           当输入的数据不是1-1000之间的数字时,输出提示语句,用户重新输入,结果如下。当输入符合要求时,输出四则运算表达式及正确答案,如下图所示:

小学生四则运算练习项目报告

      3、Eclipse执行情况和result.txt文件的输入情况:

小学生四则运算练习项目报告

五、核心代码

      1、文件定义

          (1)第一行代码是使用JDK自带的类调用JS,实现执行字符串中的运算公式的功能。JAVA使用ScriptEngine解析脚本,ScriptEngineManager是一个工厂的集合,可以通过name或者tag的方式获取某一个脚本的

工厂,并且生成一个脚本的ScriptEngine,ScriptEngine是一个脚本引擎,包含eval操作方法;

          (2)定义文件,如果没有则自己创建文件。

1         ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
2         File file = new File("result.txt");  //生成保存结果的文件
3         FileOutputStream fop = new FileOutputStream(file);
4         
5         //如果没有文件,自己创建
6         if (!file.exists()) {
7            file.createNewFile();
8         }

       2、异常处理

            接受用户输入的参数x,使用while判断x是否在1-1000之间,若不在则抛出异常,重新输入;若符合则将x作为要生成的题目的数量。

 1         String s = "";
 2         int x=-1; //题目数量        
 3         System.out.println("请输入题目的数量:");
 4         Scanner scan2 = new Scanner(System.in);
 5         while(x < 1 || x > 1000)
 6         {
 7                   try{
 8                       x = scan2.nextInt();
 9                   }catch(Exception e){
10                       System.out.println("输入不符合要求,请重新输入");
11                       scan2.next();
12                       x=-1;
13                 }
14                 if((x < 1 || x > 1000) && x != -1)
15                      System.out.println("输入不符合要求,请重新输入");
16         }     

          3、产生运算式以及结果的计算和处理

                (1)定义num保存算式的结果;定义q保存算式,类型为字符串;定义a、b、c、d、e产生1-100之间的五个随机数;

                (2)定义z保存一个3-5之间的随机数,用来设定运算式的数值个数,分类讨论;每种情况下都产生了一个1-4之间的随机数,每个数代表一个运算符,使用switch来判断;

                (3)代码19-48行是z=3的情况,有三个运算数,两个运算符;代码50-89行是z=4的情况,有四个运算数,三个运算符;代码91-141行是z=5的情况,有五个运算数,四个运算符;

                (4)142行代码调用eval方法,识别运算式,可自动识别优先级,计算出结果存入hush变量中,hush为String类型;

                (5)143行将结果hush转换为Double类型,存到变量result中;

                (6) 145-148处理结果是否为负数和非整数,将算式和结果写入文件,并在Eclipse中打印;

                (7)149行将变量重置,进行下一次循环。

  1         int a = 0;//运算式的第一个随机数
  2         int b = 0;//运算式的第二个随机数
  3         int c = 0;//运算式的第三个随机数
  4         int d = 0;//运算式的第四个随机数
  5         int e = 0;//运算式的第五个随机数
  6         
  7         int num = 0;//结果
  8         String q="";      //保存运算式
  9         Random random = new Random();    
 10         int i=0;
 11         while(i<x){
 12             a = (int) (Math.random()*100+1);
 13             b = (int) (Math.random()*100+1);
 14             c = (int) (Math.random()*100+1);
 15             d = (int) (Math.random()*100+1);
 16             e = (int) (Math.random()*100+1);
 17             
 18             int z = random.nextInt(5)%(5-3+1) + 3;//产生一个3-5之间的随机数,用来设定运算式的数值个数        
 19             if(z == 3){
 20                 //3个数,则产生两个运算符
 21                 int A = random.nextInt(4)%(4-1+1) + 1;
 22                 switch(A){
 23                     case 1: num = a + b;
 24                     q = a + "+" + b;  
 25                     break;
 26                     case 2: num = a - b;
 27                     q = a + "-" + b;
 28                     break;
 29                     case 3: num = a * b;
 30                     q = a + "*" + b;
 31                     break;
 32                     default : 
 33                     num = a / b; q = a + "/" + b;
 34                     break;
 35                 }
 36                 int B = random.nextInt(4)%(4-1+1) + 1;
 37                 switch(B){
 38                     case 1: num = num + c; q = q + "+" + c;
 39                     break;
 40                     case 2: num = num - c; q = q + "-" + c;
 41                     break;
 42                     case 3: num = num * c; q = q + "*" + c;
 43                     break;
 44                     default : 
 45                         num = num / c; q = q + "/" + c;
 46                     break;
 47                 }
 48             }
 49             
 50             if(z == 4){
 51                 //4个数,则产生三个运算符
 52                 int A = random.nextInt(4)%(4-1+1) + 1;
 53                 switch(A){
 54                     case 1: num = a + b;  q = a + "+" + b; 
 55                     break;
 56                     case 2: num = a - b;  q = a + "-" + b; 
 57                     break;
 58                     case 3: num = a * b; q = a + "*" + b; 
 59                     break;
 60                     default : 
 61                         num = a / b; q = a + "/" + b; 
 62                     break;
 63                 }
 64                 int B = random.nextInt(4)%(4-1+1) + 1;
 65                 switch(B){
 66                     case 1: num = num + c;  q = q + "+" + c; 
 67                     break;
 68                     case 2: num = num - c;   q = q + "-" + c; 
 69                     break;
 70                     case 3: num = num * c;   q = q + "*" + c; 
 71                     break;
 72                     default :
 73                         num = num / c;  q = q + "/" + c; 
 74                     break;
 75                 }
 76                 
 77                 int C = random.nextInt(4)%(4-1+1) + 1;
 78                 switch(C){
 79                     case 1: num = num + d;    q = q + "+" + d; 
 80                     break;
 81                     case 2: num = num - d;     q = q + "-" + d; 
 82                     break;
 83                     case 3: num = num * d;    q = q + "*" + d; 
 84                     break;
 85                     default :
 86                         num = num / d;  q = q + "/" + d; 
 87                     break;
 88                 }
 89             }
 90             
 91             if(z == 5){
 92                 //5个数,则产生4个运算符
 93                 int A = random.nextInt(4)%(4-1+1) + 1;
 94                 switch(A){
 95                     case 1: num = a + b;   q = a + "+" + b; 
 96                     break;
 97                     case 2: num = a - b;   q = a + "-" + b;
 98                     break;
 99                     case 3: num = a * b;   q = a + "*" + b;
100                     break;
101                     default :
102                     num = a / b; q = a + "/" + b; 
103                     break;
104                 }
105                 int B = random.nextInt(4)%(4-1+1) + 1;
106                 switch(B){
107                     case 1: num = num + c;  q = q + "+" + c;
108                     break;
109                     case 2: num = num - c;  q = q + "-" + c;
110                     break;
111                     case 3: num = num * c; q = q + "*" + c;
112                     break;
113                     default : 
114                     num = num / c;  q = q + "/" + c; 
115                     break;
116                 }
117                 int C = random.nextInt(4)%(4-1+1) + 1;
118                 switch(C){
119                     case 1: num = num + d;    q = q + "+" + d; 
120                     break;
121                     case 2: num = num - d;      q = q + "-" + d; 
122                     break;
123                     case 3: num = num * d;      q= q + "*" + d; 
124                     break;
125                     default : 
126                     num = num / d;  q = q + "/" + d;  
127                     break;
128                 }
129                 int D = random.nextInt(4)%(4-1+1) + 1;
130                 switch(D){ 
131                     case 1:     q = q + "+" + e; 
132                     break; 
133                     case 2:     q = q + "-" + e; 
134                     break;
135                     case 3:     q = q + "*" + e; 
136                     break;
137                     default : 
138                                 num = num / d;  q = q + "/" + e;  
139                     break;
140                 }
141             }
142             String hush=String.valueOf(jse.eval(q));
143             Double result=Double.parseDouble(hush);
144         
145             if(result<0 || result%1!=0)  {   continue;  }   //结果不能为负数和非整数
146             fop.write((q+"=" + jse.eval(q)).getBytes());    //写入表达式
147             fop.write("\r\n".getBytes());   //换行
148             System.out.println(q+"="+jse.eval(q));
149             q="";    result=(double) 0;  i++; //重新置为空,重新开始
150         }

六、总结

       这次设计主要包括三个部分,文件的产生和定义、异常处理以及运算式的产生以及结果的计算和处理。设计时最困难的就是运算式的产生和结果的处理,最后调用eval方法使得

运算式计算时不需要考虑优先级,实现简单了很多。

七、PSP展示

PSP2.1 任务内容 计划完成的时间(min) 实际完成需要的时间(min)
PLanning 计划 20 20
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 20 40
Developmet 开发 240 320
Analysis 需求分析(包括学习新技术) 20 30
Design Spec 生成设计文档 5 5
Design Revie 设计复审(和同事审核设计文档) 5 4
Coding Standard 代码规范 2 2
Design 具体设计 40 50
Coding 具体编码 120 140
Code Review 代码复审 5 5
Test 测试(自我测试,修改代码,提交修改) 30 45
Reporting 报告 30 40
Test Report 测试报告 8 10
Size Measurement 计算工作量 3 3
Postmortem & Process Improvement Plan 事后总结,并提出过程改机计划 10 15

 项目总结:

        本次项目在刚开始分析问题时觉得不是特别困难,但实际设计时发现要考虑的问题很多,其中问题最多的就是运算式的产生和结果的处理,刚开始运算符的优先级一直有问题,

导致结果不正确,最后使用ScriptEngine解析脚本,调用eval方法处理结果,不用再对运算符进行优先级处理,比较投机取巧,使得代码比较之前简化了很多,节省了大量的时间。

这次代码写的比较简单,由于能力有限,没有实现附加功能,以后会继续努力,希望自己做的更好。