任务1源码在Github的仓库主页链接地址:

https://github.com/zhanghh2018/Four-primary-school-pupils

需求分析:

  1. 作业总体效果:随机产生n道加减乘除练习题;
  2. 练习题的构成:数字和运算符且每个数字在 0 和 100 之间,运算符在3个到5个之间且每个练习题至少要包含2种运算符;
  3. 练习题的结果:练习题在运算过程中不出现负数与非整数;
  4. 最终提交结果:学号与生成的n道练习题及其对应的正确答案;样例如下:

功能设计:

  1. 表达式的生成模块。首先需要生成运算符与数字,每个等式中运算符的个数加一就等于该等式中的数字个数,之后将生成的符号与数字组合成String,传入逆波兰计算模块进行结果的输出。在此模块中将除法中分母为零的情况、运算符只有一种的情况以及分子分母除不尽的情况排除。
  2. 表达式的计算模块。利用逆波兰表达式计算结果,在该模块中排除例如30/6/3这样的情况,在之前的模块中排除的只是除号前后的分子分母的情况,并未考虑除号连续的情况,当除号连续时,需要考虑第一个除号运算完之后的结果能否继续除以下一个数的情况,当遇到前后余数不为0的情况以及中间结果为负数的情况就跳出该函数,继续产生新的等式直至满足条件。写这个模块的时候借鉴这位博主的写法(http://blog.csdn.net/u010485491/article/details/51483720);
  3. 结果写入文件模块。将自己的学号与根据用户输入的题目个数生成的等式写入文件。
  4. 异常情况的处理。排除输入为非数字的情况以及输入的数字大于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--;
}
}

总结:

  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  设计复审 (和同事审核设计文档)   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的更多相关文章

  1. 小学生四则运算JAVA

    点我,github地址 组员:黄浩格,何坤 一.项目说明 1题目:实现一个自动生成小学四则运算题目的命令行程序. 2说明: 自然数:0, 1, 2, -. • 真分数:1/2, 1/3, 2/3, 1 ...

  2. 3.结对编程成果报告(小学生四则运算的出题程序,Java实现)

    程序名称:小学生四则运算的出题程序 先附上代码: package com.makequestion; import java.text.DecimalFormat;import java.util.R ...

  3. 30道小学生四则运算题C/C++编程

    软件工程科课上,老师通过实例讲解什么是程序,程序和软件的区别,要求我们通过短时间写一道编程题, 题目就是编写30道小学生四则运算题.以下就是源代码: #include<iostream.h> ...

  4. java小学生四则运算带面板版 但我不知道为什么同类变量却进不了动作监听中去

    ---恢复内容开始--- package yun; import java.util.*; import java.awt.*; import java.awt.event.ActionEvent; ...

  5. 作业六:小学生四则运算之NABCD模型与产品Backlog。

    NABCD模型与产品Backlog NABCD模型 ) N (Need 需求) 方便了老师和学生,使他们可以想要的时候随时可以得到,省时省力,快速出题,马上得到答案. ) A (Approach 做法 ...

  6. JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)

    switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...

  7. 《Java编程思想》学习笔记(二)——类加载及执行顺序

    <Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...

  8. #Java编程思想笔记(一)——static

    Java编程思想笔记(一)--static 看<Java编程思想>已经有一段时间了,一直以来都把笔记做在印象笔记上,今天开始写博客来记录. 第一篇笔记来写static关键字. static ...

  9. [Java编程思想-学习笔记]第3章 操作符

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  10. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

随机推荐

  1. [Swift]LeetCode436. 寻找右区间 | Find Right Interval

    Given a set of intervals, for each of the interval i, check if there exists an interval j whose star ...

  2. [Swift]LeetCode952. 按公因数计算最大组件大小 | Largest Component Size by Common Factor

    Given a non-empty array of unique positive integers A, consider the following graph: There are A.len ...

  3. Hystrix概念设计

    1. Hystrix概念设计 1.1. 大纲 1.2. 基本的容错模式 1.3. 断路器模式 1.4. 舱壁隔离模式 1.5. 容错理念 凡事依赖都可能失败 凡事资源都有限制 网络并不可靠 延迟是应用 ...

  4. Mysql、Hbuilder、Idea快捷键

    MyEclipse 快捷键 ↑ ↓ ← →多 1.方法抽取,Alt+Shift+M 2.多行注释:Ctrl+Shift+/ 3.对象.方法; Ctrl+2 + ↓+回车 ,自动生成返回类型和变量 (非 ...

  5. 第二周 IP通信基础回顾

    这周我们学习了OSI参考模型,了解局域网的分层为接入层,汇聚层,核心层.网络划分为通信直网,资源直网.osi模型概述在主动间数据传输为应用层,表示层,会话层:底层数据l流为传输层,网络层,数据链路层, ...

  6. 【Redis篇】初始Redis与Redis安装

    一.前述 Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相对更多,包括st ...

  7. 【机器学习】--线性回归中soft-max从初始到应用

    一.前述 Soft-Max是做多分类的,本身是哪个类别的概率大,结果就为对应的类别.为什么称之为Soft判别,原因是归一化之后的概率选择最大的作为结果,而不是只根据分子. 二.原理 sigmod函数: ...

  8. 简单实现 C# 与 Javascript的兼容

    本文章介绍下自己这刚实现的一个c#与js交互的插件.需求来源于一次与朋友的讨论.主要对话如下: 朋友:最近我想模拟一些数据,来测试我现在写的接口,但手工编写这些测试数据太麻烦了 本人:是啊,.net能 ...

  9. solr之环境配置四

    Solr链接数据库(mysql,mssql) 一.链接mysql 1.使用DataImportHandler导入并索引数据,配置 $SOLR_HOME\core0\conf\solrconfig.xm ...

  10. AngularJS2+调用原有的js脚本(AngularJS脚本跟本地原有脚本之间的关系)

    昨天一个话题说关于AngularJS2以后版本的两个小技巧,不料引出了另外一个话题,话题起始很简单: "很多的前端框架并不复杂,比如JQuery,引入即用,实时看到效果,多好.到了Angul ...