小学生四则运算(java编程)201571030135
任务1源码在Github的仓库主页链接地址:
https://github.com/zhanghh2018/Four-primary-school-pupils
需求分析:
- 作业总体效果:随机产生n道加减乘除练习题;
- 练习题的构成:数字和运算符且每个数字在 0 和 100 之间,运算符在3个到5个之间且每个练习题至少要包含2种运算符;
- 练习题的结果:练习题在运算过程中不出现负数与非整数;
- 最终提交结果:学号与生成的n道练习题及其对应的正确答案;样例如下:
功能设计:
- 表达式的生成模块。首先需要生成运算符与数字,每个等式中运算符的个数加一就等于该等式中的数字个数,之后将生成的符号与数字组合成String,传入逆波兰计算模块进行结果的输出。在此模块中将除法中分母为零的情况、运算符只有一种的情况以及分子分母除不尽的情况排除。
- 表达式的计算模块。利用逆波兰表达式计算结果,在该模块中排除例如30/6/3这样的情况,在之前的模块中排除的只是除号前后的分子分母的情况,并未考虑除号连续的情况,当除号连续时,需要考虑第一个除号运算完之后的结果能否继续除以下一个数的情况,当遇到前后余数不为0的情况以及中间结果为负数的情况就跳出该函数,继续产生新的等式直至满足条件。写这个模块的时候借鉴这位博主的写法(http://blog.csdn.net/u010485491/article/details/51483720);
- 结果写入文件模块。将自己的学号与根据用户输入的题目个数生成的等式写入文件。
- 异常情况的处理。排除输入为非数字的情况以及输入的数字大于1000、小于1以及等于0的情况。
基本功能:
- 实现每道练习题运算符在3个到5个之间,至少要包含2种运算符;
- 运算结果无负数以及非整数;
- 将最终结果保存在文档中以样例为模板;
- 每道练习题的结果不超过一定的范围(考虑到小学生计算能力有限,当时问了郑老师,在老师的提示下,设置了用户输入想要生成结果的范围这一块内容,并进行了异常处理)。
设计实现:
利用Visio进行流程图的绘制,具体流程图如下:其中ContentToTxt(将结果写入文件) Main(主程序可以从命令行接收参数) ReversePolish (逆波兰表达式) RandomEquation(产生等式) result.txt(运行后产生的结果)
测试运行:
核心代码:
1) 随机产生等式模块:为了看起来整洁,去掉了测试过程中注释掉的打印输出部分。等式生成是将生成的数字与运算符依次拼接,之后加上等号构成等式,在构建过程中去除运算符只有一种的情况、分母为0的情况,分子分母有余数的情况。
public class RandomEquation {
public static String randomEquation (){ // Previous expressions String sBefore = new String(); // The later expression String sLater = new String();
char[] equation;
int k = 6;
int n;
int m;
int j;
int i;
int[] number;
char[] symbol;
number = new int[k];
symbol = new char[k];
equation = new char[2 * k];
char[] cSymbol = {'+','-','*','÷'};
Random random = new Random(); // Generating operator for(i = 0;i<(int)(Math.random()*3)+3;i++){
int index = random.nextInt(cSymbol .length);
char resultChar = cSymbol[index];
symbol[i] = resultChar; }
for(m = 0;m < i;m++){
if(symbol[i - 1] != symbol[m]){
break;
}
} /*
* Removal of only one operator
* If the last symbol is the same as the previous one, the last one generates a symbol at random.
*/ if(m == i){
do{
int index = random.nextInt(cSymbol.length);
char resultChar = cSymbol[index];
symbol[i - 1] = resultChar;
}while(symbol[i - 1] == symbol[i - 2]);
} // Generating number for(j = 0;j < i + 1;j++){ int num = (int)(Math.random()*100);
number[j] = num; } // Generating equation for(n = 0;n < i;n++){
sBefore += String.valueOf(number[n])+String.valueOf(symbol[n]);
}
sBefore += String.valueOf(number[i]); // Save symbols and numbers into a equation array for(n = 1;n < 2 * i;n = n+2){ equation[n] = symbol[(n - 1) / 2];
}
for(n = 0;n < 2 * j - 1;n = n+2){ equation[n] = (char)number[(n + 1) / 2]; } // The removal ÷ denominator is 0 and the molecular denominator is incompatible for(n = 1;n < i + j && n + 1 < i + j;n = n + 2){
if(equation[n] == '÷'){
if(equation[n + 1]==0){
do{
int num2 = (int)(Math.random()*100);
equation[n + 1] = (char)num2;
}while(equation[n + 1] == 0);
}
else if((int)equation[n - 1] % (int)equation[n + 1]!=0 || (int)equation[n - 1]<(int)equation[n + 1]){
do{ int num2 = (int)(Math.random()*100) + 1;
equation[n + 1] = (char)num2;
if(equation[n + 1] == 0){
do{
int num3 = (int)(Math.random()*100);
equation[n + 1] = (char)num3;
}while(equation[n + 1] == 0);
} }while((int)equation[n - 1] % (int)equation[n + 1]!= 0 || (int)equation[n - 1]<(int)equation[n + 1]);
} } }
// The equation after excluding special circumstances for(n = 0;n < i+j && n + 1 < i + j;n = n + 2){ sLater += String.valueOf((int)equation[n]);
sLater += String.valueOf(equation[n + 1]); }
sLater += String.valueOf((int)equation[i + j - 1]);
sLater += String.valueOf('='); return sLater;
} }
2)逆波兰模块借鉴这位博主的写法,并在理解的基础上进行了代码的加工。当中间结果小于0或者a%b!=0时,利用return跳出该函数,并在下边的模块中利用返回值进行等式的重新生成。 http://blog.csdn.net/u010485491/article/details/51483720
public static int calcInt(int a, int b, String stmp)
{
int res = 0;
char s = stmp.charAt(0);
switch (s) {
case '+': {
res = a + b;
break;
}
case '-': {
res = a - b;
if(res < 0){
return -1;
}
break;
}
case '*': {
res = a * b;
break;
}
case '÷': {
res = a / b;
if( a % b != 0){
return -1;
}
break;
}
}
return res;
}
3)结果写入文件模块,由于随机产生等式,所以需要一直将该等式保存到字符串里,并对该字符串进行逆波兰求解,否则若随机产生式子randomEquation(),之后又利用ReversePolish(randomEquation()))产生的随机等式的结果,这样会出现等式计算结果与最终运算结果不匹配的情况。在该模块中利用返回值的不同进行结果的保存,若返回值为-1或者大于用户输入的结果值result,就将i的值自减,这样就相当于重新产生符合条件的式子。
for(int i = 0;i < questionAmount;i++){ String randoms = randomEqual.randomEquation();
final boolean existed = reversePolish.reversePolish(randoms) != -1 && reversePolish.reversePolish(randoms) < 500;
if(existed){ contentToTxt.contentToTxt(strFilePath,String.valueOf(randoms+reversePolish.reversePolish(randoms)));
contentToTxt.contentToTxt(strFilePath,String.valueOf("\n"));
}else{
i--;
}
}
总结:
- 在拿到题目的时候,并没有急着去完成代码而是首先进行了需求分析,根据需求分析将本次作业分为三大模块,并对这三个模块进行了功能的划分,每个模块都有要实现的功能,且尽量降低模块之间的联系。以这样的做法书写下来发现思路很清晰,由于不再在一个函数体内书写程序,一个模块出了问题不必全篇找,直接在这个模块中修改即可。
- 由于参加完蓝桥杯之后就没有与java打交道了,一直与c语言打交道,所以java当中的语法也遗忘了不少,使用new这一关键字创建对象也给忘记啦,突然想到一则笑话(甲说都大三了,连女朋友都没有。乙说:new一个‘对象’),这下子就忘不了啦。
- 在书写代码的过程中使用了do while语句,不需要判断循环次数,以前一直在使用while语句,这次在产生表达式的过程中大量使用了do while,深刻体会到了该语句的妙处。
- 在考虑情况的时候并不是一次性完成的,而是在编写代码的过程中慢慢想出来的,到了最后计算结果的时候发现结果已经有上万的啦,所以将输出结果限制在用户要求的范围内,这样就和小学生实际情况相符合。
- 在生成表达式中去除分子分母不能整除的时候,例如a/b/c判断,若a/b不能整除就再随机产生a,b;若同时b/c不能整除则再随机产生b,c;这样下来发现会产生a/b不能整除的情况,因为b随机了两次,后一次随机就无法保证a/b是整数了,所以想到在逆波兰计算的时候进一步排除连续除号除不尽的情况。
- 最后写的是文件模块,由于是将之前写的文档import进去的,在测试是否写好文件的时候发现在目录JRE System Library下边没有产生文件,最后在打开的文件夹中找到了,所以之后的每一次运行就拿Windows自带的记事本打开,明明写了换行符但仍在一行上,测试了好几次都不对,最后和同学交流了才发现这个问题,利用notepad++打开结果就是合适的。
- 本来是想进行附加功能的添加,然而做的时候将一些特殊请款考虑到生成表达式的模块中,导致这些附加功能无法实现,比如真分数的计算,在生成表达式的过程中,将分子分母除不尽的情况已经排除,另外就是加括号的情况,在此模块中将除法中出现的分母为零的情况排除,排除的时候只看除号后边的数字,如果加上括号就没办法进行特殊情况的判断。所以还是在写的时候全盘考虑,不能只想着实现这些基本功能,使得算法没有拓展性。
PSP:
PSP2.1 | 任务内容 | 计划完成需要的时间(min) | 实际完成需要的时间(min) |
Planning | 计划 | 20 | 25 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 20 | 25 |
Development | 开发 | 360 | 418 |
Analysis | 需求分析 (包括学习新技术) | 10 | 10 |
Design Spec | 生成设计文档 | 10 | 8 |
Design Review | 设计复审 (和同事审核设计文档) | 10 | 15 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
Design | 具体设计 | 30 | 35 |
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 |
小学生四则运算(java编程)201571030135的更多相关文章
- 小学生四则运算JAVA
点我,github地址 组员:黄浩格,何坤 一.项目说明 1题目:实现一个自动生成小学四则运算题目的命令行程序. 2说明: 自然数:0, 1, 2, -. • 真分数:1/2, 1/3, 2/3, 1 ...
- 3.结对编程成果报告(小学生四则运算的出题程序,Java实现)
程序名称:小学生四则运算的出题程序 先附上代码: package com.makequestion; import java.text.DecimalFormat;import java.util.R ...
- 30道小学生四则运算题C/C++编程
软件工程科课上,老师通过实例讲解什么是程序,程序和软件的区别,要求我们通过短时间写一道编程题, 题目就是编写30道小学生四则运算题.以下就是源代码: #include<iostream.h> ...
- java小学生四则运算带面板版 但我不知道为什么同类变量却进不了动作监听中去
---恢复内容开始--- package yun; import java.util.*; import java.awt.*; import java.awt.event.ActionEvent; ...
- 作业六:小学生四则运算之NABCD模型与产品Backlog。
NABCD模型与产品Backlog NABCD模型 ) N (Need 需求) 方便了老师和学生,使他们可以想要的时候随时可以得到,省时省力,快速出题,马上得到答案. ) A (Approach 做法 ...
- JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)
switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...
- 《Java编程思想》学习笔记(二)——类加载及执行顺序
<Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...
- #Java编程思想笔记(一)——static
Java编程思想笔记(一)--static 看<Java编程思想>已经有一段时间了,一直以来都把笔记做在印象笔记上,今天开始写博客来记录. 第一篇笔记来写static关键字. static ...
- [Java编程思想-学习笔记]第3章 操作符
3.1 更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...
- Java编程思想重点笔记(Java开发必看)
Java编程思想重点笔记(Java开发必看) Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...
随机推荐
- [Swift]LeetCode452. 用最少数量的箭引爆气球 | Minimum Number of Arrows to Burst Balloons
There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided ...
- [Swift]LeetCode834. 树中距离之和 | Sum of Distances in Tree
An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given. The ith edge co ...
- [Swift]LeetCode1020. 飞地的数量 | Number of Enclaves
Given a 2D array A, each cell is 0 (representing sea) or 1 (representing land) A move consists of wa ...
- Android开发:修改eclipse里的Android虚拟机路径
一.发现问题: 今天打开电脑发现C盘缩了不少,这才意识到:eclipse里配置的安卓虚拟机默认放在了C盘里. 当然,在不同的电脑上可能路径有所不同,我的默认路径是:C:\Users\lenovo\.a ...
- Chorme浏览器渲染MathJax时出现竖线的解决方法
Chorme浏览器渲染MathJax时出现竖线的原因分析与解决方法 查资料知,Chorme中显示MathJax时出现竖线的原因如下: 新版的Chorme浏览器在解析css时,会对其中的值进行向上取整( ...
- 深入理解Spring IOC工作原理
为什么会出现spring,spring出现解决了什么问题? 1.分析普通多层架构存在的问题 JSP->Servlet->Service->Dao 层与层之间的依赖很强,属于耦合而且是 ...
- Java基础10:全面解读Java异常
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- spring cloud 配置zuul实用
在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡 ...
- 按行切割大文件(linux split 命令简版)
按行切割大文件(linux split 命令简版) #-*- coding:utf-8 -*- __author__ = 'KnowLifeDeath' ''' Linux上Split命令可以方便对大 ...
- 杭电ACM2005--第几天?
第几天? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...