⼩学⽣四则运算(java编程)201571030135任务1源码在Github的仓库主页链接地址:
需求分析:
1. 作业总体效果:随机产⽣n道加减乘除练习题;
2. 练习题的构成:数字和运算符且每个数字在 0 和 100 之间,运算符在3个到5个之间且每个练习题⾄少要包含2种运算符;
3. 练习题的结果:练习题在运算过程中不出现负数与⾮整数;
4. 最终提交结果:学号与⽣成的n道练习题及其对应的正确答案;样例如下:
功能设计:
1. 表达式的⽣成模块。⾸先需要⽣成运算符与数字,每个等式中运算符的个数加⼀就等于该等式中的数字个数,之后将⽣成的符号与数
字组合成String,传⼊逆波兰计算模块进⾏结果的输出。在此模块中将除法中分母为零的情况、运算符只有⼀种的情况以及分⼦分母除不尽的情况排除。
2. 表达式的计算模块。利⽤逆波兰表达式计算结果,在该模块中排除例如30/6/3这样的情况,在之前的模块中排除的只是除号前后的分⼦
分母的情况,并未考虑除号连续的情况,当除号连续时,需要考虑第⼀个除号运算完之后的结果能否继续除以下⼀个数的情况,当遇到前后余数不为0的情况以及中间结果为负数的情况就跳出该函数,继续产⽣新的等式直⾄满⾜条件。写这个模块的时候借鉴这位博主的写法();
3. 结果写⼊⽂件模块。将⾃⼰的学号与根据⽤户输⼊的题⽬个数⽣成的等式写⼊⽂件。
4. 异常情况的处理。排除输⼊为⾮数字的情况以及输⼊的数字⼤于1000、⼩于1以及等于0的情况。
基本功能:
实现每道练习题运算符在3个到5个之间,⾄少要包含2种运算符;
运算结果⽆负数以及⾮整数;
将最终结果保存在⽂档中以样例为模板;
每道练习题的结果不超过⼀定的范围(考虑到⼩学⽣计算能⼒有限,当时问了郑⽼师,在⽼师的提⽰下,设置了⽤户输⼊想要⽣成结果的范围这⼀块内容,并进⾏了异常处理)。
设计实现:
利⽤Visio进⾏流程图的绘制,具体流程图如下:其中ContentToTxt(将结果写⼊⽂件) Main(主程序可以从命令⾏接收参数) ReversePolish (逆波兰表达式) RandomEquation(产⽣等式) (运⾏后产⽣的结果)
测试运⾏:
核⼼代码:
1)随机产⽣等式模块:为了看起来整洁,去掉了测试过程中注释掉的打印输出部分。等式⽣成是将⽣成的数字与运算符依次拼接,之后加上等号构成等式,在构建过程中去除运算符只有⼀种的情况、分母为0的情况,分⼦分母有余数的情况。
1public class RandomEquation {
2public static String randomEquation (){
3
4// Previous expressions
5
6        String sBefore = new String();
7
8// The later expression
9
10        String sLater = new String();
11char[] equation;
12int k = 6;
13int n;
14int m;
15int j;
16int i;
17int[] number;
18char[] symbol;
19        number = new int[k];
20        symbol = new char[k];
21        equation = new char[2 * k];
22char[] cSymbol = {'+','-','*','÷'};
23        Random random = new Random();
24
25// Generating operator
26
27for(i = 0;i<(int)(Math.random()*3)+3;i++){
28int index = Int(cSymbol .length);
29char resultChar = cSymbol[index];
30            symbol[i] = resultChar;
31
32        }
33for(m = 0;m < i;m++){
34if(symbol[i - 1] != symbol[m]){
35break;
36            }
37        }
38
39/*
40        * Removal of only one operator
41        * If the last symbol is the same as the previous one, the last one generates a symbol at random.
42*/
43
44if(m == i){
45do{
46int index = Int(cSymbol.length);
47char resultChar = cSymbol[index];
48                symbol[i - 1] = resultChar;
49            }while(symbol[i - 1] == symbol[i - 2]);
50        }
51
52// Generating number
53
54for(j = 0;j < i + 1;j++){
55
56int num = (int)(Math.random()*100);
57            number[j] = num;
58
59        }
60
61// Generating equation
62
63for(n = 0;n < i;n++){
64            sBefore += String.valueOf(number[n])+String.valueOf(symbol[n]);
65        }
66        sBefore += String.valueOf(number[i]);
67
68// Save symbols and numbers into a equation array
69
70for(n = 1;n < 2 * i;n = n+2){
71
72            equation[n] = symbol[(n - 1) / 2];
73        }
74for(n = 0;n < 2 * j - 1;n = n+2){
75
76            equation[n] = (char)number[(n + 1) / 2];
77
78        }
79
80// The removal ÷ denominator is 0 and the molecular denominator is incompatible
81
82for(n = 1;n < i + j && n + 1 < i + j;n = n + 2){
83if(equation[n] == '÷'){
84if(equation[n + 1]==0){
85do{
86int num2 = (int)(Math.random()*100);
87                        equation[n + 1] = (char)num2;
88                    }while(equation[n + 1] == 0);
do while语句流程图89                }
90else if((int)equation[n - 1] % (int)equation[n + 1]!=0 || (int)equation[n - 1]<(int)equation[n + 1]){
91do{
92
93int num2 = (int)(Math.random()*100) + 1;
94                        equation[n + 1] = (char)num2;
95if(equation[n + 1] == 0){
96do{
97int num3 = (int)(Math.random()*100);
98                                equation[n + 1] = (char)num3;
99                            }while(equation[n + 1] == 0);
100                        }
101
102                    }while((int)equation[n - 1] % (int)equation[n + 1]!= 0 || (int)equation[n - 1]<(int)equation[n + 1]);
103                }
104
105            }
106
107
108        }
109// The equation after excluding special circumstances
110
111for(n = 0;n < i+j && n + 1 < i + j;n = n + 2){
112
113            sLater += String.valueOf((int)equation[n]);
114            sLater += String.valueOf(equation[n + 1]);
115
116        }
117        sLater += String.valueOf((int)equation[i + j - 1]);
118        sLater += String.valueOf('=');
119
120return sLater;
121    }
122
123 }
2)逆波兰模块借鉴这位博主的写法,并在理解的基础上进⾏了代码的加⼯。当中间结果⼩于0或者a%b!=0时,利⽤return跳出该函数,并在下边的模块中利⽤返回值进⾏等式的重新⽣成。
1public static int calcInt(int a, int b, String stmp)
2    {
3int res = 0;
4char s = stmp.charAt(0);
5switch (s) {
6case '+': {
7            res = a + b;
8break;
9          }
10case '-': {
11            res = a - b;
12if(res < 0){
13return -1;
14            }
15break;
16          }
17case '*': {
18            res = a * b;
19break;
20          }
21case '÷': {
22            res = a / b;
23if( a % b != 0){
24return -1;
25            }
26break;
27          }
28        }
29return res;
30    }
3)结果写⼊⽂件模块,由于随机产⽣等式,所以需要⼀直将该等式保存到字符串⾥,并对该字符串进⾏逆波兰求解,否则若随机产⽣式⼦randomEquation(),之后⼜利⽤ReversePolish(randomEquation()))产⽣的随机等式的结果,这样会出现等式计算结果与最终运算结果不匹配的情况。在该模块中利⽤返回值的不同进⾏结果的保存,若返回值为-1或者⼤于⽤户输⼊的结果值result,就将i的值⾃减,这样就相当于重新产⽣符合条件的式⼦。
1for(int i = 0;i < questionAmount;i++){
2
3            String randoms = randomEqual.randomEquation();
4final boolean existed = versePolish(randoms) != -1 && versePolish(randoms) < 500;
5if(existed){
6
7                tToTxt(strFilePath,String.valueOf(versePolish(randoms)));
8                tToTxt(strFilePath,String.valueOf("\n"));
9            }else{
10                i--;
11            }
12        }
总结:
1. 在拿到题⽬的时候,并没有急着去完成代码⽽是⾸先进⾏了需求分析,根据需求分析将本次作业分为三⼤模块,并对这三个模块进⾏
了功能的划分,每个模块都有要实现的功能,且尽量降低模块之间的联系。以这样的做法书写下来发现思路很清晰,由于不再在⼀个函数体内书写程序,⼀个模块出了问题不必全篇,直接在这个模块中修改即可。
2. 由于参加完蓝桥杯之后就没有与java打交道了,⼀直与c语⾔打交道,所以java当中的语法也遗忘了不少,使⽤new这⼀关键字创建对
象也给忘记啦,突然想到⼀则笑话(甲说都⼤三了,连⼥朋友都没有。⼄说:new⼀个‘对象’),这下⼦就忘不了啦。
3. 在书写代码的过程中使⽤了do while语句,不需要判断循环次数,以前⼀直在使⽤while语句,这次在产⽣表达式的过程中⼤量使⽤了
do while,深刻体会到了该语句的妙处。
4. 在考虑情况的时候并不是⼀次性完成的,⽽是在编写代码的过程中慢慢想出来的,到了最后计算结果的时候发现结果已经有上万的
啦,所以将输出结果限制在⽤户要求的范围内,这样就和⼩学⽣实际情况相符合。
5. 在⽣成表达式中去除分⼦分母不能整除的时候,例如a/b/c判断,若a/b不能整除就再随机产⽣a,b;若同时b/c不能整除则再随机产⽣b,c;这
样下来发现会产⽣a/b不能整除的情况,因为b随机了两次,后⼀次随机就⽆法保证a/b是整数了,所以想到在逆波兰计算的时候进⼀步排除连续除号除不尽的情况。
6. 最后写的是⽂件模块,由于是将之前写的⽂档import进去的,在测试是否写好⽂件的时候发现在⽬录JRE System Library下边没有产⽣
⽂件,最后在打开的⽂件夹中到了,所以之后的每⼀次运⾏就拿Windows⾃带的记事本打开,明明写了换⾏符但仍在⼀⾏上,测试了好⼏次都不对,最后和同学交流了才发现这个问题,利⽤notepad++打开结果就是合适的。
7. 本来是想进⾏附加功能的添加,然⽽做的时候将⼀些特殊请款考虑到⽣成表达式的模块中,导致这些附加功能⽆法实现,⽐如真分数
的计算,在⽣成表达式的过程中,将分⼦分母除不尽的情况已经排除,另外就是加括号的情况,在此模块中将除法中出现的分母为零的情况排除,排除的时候只看除号后边的数字,如果加上括号就没办法进⾏特殊情况的判断。所以还是在写的时候全盘考虑,不能只想着实现这些基本功能,使得算法没有拓展性。
PSP:
PSP2.1任务内容计划完成需要的时间(min)实际完成需要的时间(min)
Planning计划 20 25
Estimate 估计这个任务需要多少时间,并规划⼤致⼯作步骤 20 25
Development开发 360 418
Analysis 需求分析 (包括学习新技术)10  10
Design Spec⽣成设计⽂档 10 8
Design Review 设计复审 (和同事审核设计⽂档)  1015
Coding Standard代码规范 (为⽬前的开发制定合适的规范)  20 20
Design具体设计3035
Coding具体编码 240 280
Code Review代码复审 20 25
Test测试(⾃我测试,修改代码,提交修改) 20 25
Reporting报告 20 27
Test Report测试报告 5 5
Size Measurement计算⼯作量 5 12
Postmortem & Process Improvement Plan事后总结 ,并提出过程改进计划 10 10

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。