项目代码地址:https://git.coding.net/liuseshz/testt.git
一.需求分析
(1) 随机生成所需n道加减乘除练习题,以符号“+-*÷”表示。
(2) 题中每个数字为 0 和 100 之间的整数
(3) 运算符在3个到5个之间
(4) 每个练习题必包含不少于两种运算符
(5) 运算过程与结果不能出现负数与非整数
(6) 学号,练习题及正确计算结果输出至目标txt文件,输出不含其它信息。
二.功能设计
基本功能
(1)随机生成输入参数为n的n道100以内加减乘除运算(分别使用符号+-*÷来表示)。(2)实现3到5个运算符,两种以上的运算,计算过程不包含负数与非整数。
附加功能(暂不考虑)
(1)支持有括号的运算式,包括出题与求解正确答案。算式中存在的括号必须大于2个,且不得超过运算符的个数。
(2)加入支持真分数加减法的出题与运算,支持运算时分数的自动化简。
三.设计实现
在不考虑附加功能的情况下,分成生成与计算两部分。
随机数与随机运算符生成,用Random函数实现
char[] sign = { '+', '-', '*', '÷'}; // 用数组存运算符 Random random = new Random(); int m = random.nextInt(3) + 3; //随机生成3-5个运算符数 int index=(int)(Math.random()* m); char a[]=new char[m-1]; int num[]=new int[5]; for(int i=0;i
算式生成
if (m==3) { System.out.println(num[0]+a[0]+num[1]+a[1]+num[2]+a[2]+num[3]+"="+sum); } //运算符个数为3时的运算式 if (m==4) { System.out.println(num[0]+a[0]+num[1]+a[1]+num[2]+a[2]+num[3]+a[3]+ num[4]+"="+sum); } //运算符个数为4时的运算式 if (m==5) { System.out.println(num[0]+a[0]+num[1]+a[1]+num[2]+a[2]+num[3]+a[3]+ num[4]+a[4]+num[5]+"="+sum); } //运算符个数为5时的运算式
四.算法详解
由于算法知识匮乏,整个代码结构中只用到了简单的判断语句,没有考虑括号的问题,计算时准备使用逆波兰的后缀表示法,但在套用时遇到了困难,最后使用了很繁琐的办法。
下面是百度到的后缀表达式算法。
class PostToResult{ private String post; //中缀表达式转换得到的后缀表达式 private Stackstack; //用于得到计算结果的栈 public PostToResult(String post, Stack stack) { this.post = post; this.stack = stack; } //由后缀表达式得到四则运算结果的实现过程 public void operate(){ String[] strArr = post.split(" "); for(int i = 0; i < strArr.length; i++){ String temp = strArr[i]; if(isDigital(temp)){ stack.push(Integer.valueOf(temp)); }else{ int result = compute(temp); stack.push(result); } } } private int compute(String str){ int re = 0; int m = stack.pop(); int n = stack.pop(); switch(str){ case "+" : re = n + m; break; case "-" : re = n - m; break; case "*" : re = n * m; break; case "/" : re = n / m; break; default : break; } return re; } private boolean isDigital(String str){ char[] chArr = str.toCharArray(); int len = chArr.length; int count = 0; for(int i = 0; i < len; i++){ if(chArr[i] >= '0' && chArr[i] <= '9') count++; } return count == len; } public int getResult() { return stack.pop(); } }
五.测试运行
六.代码展示
部分主函数
package weektwo;import java.util.Random;import java.util.Scanner;import java.io.PrintStream;import java.util.Iterator;public class Main { public static void main(String[]args) { Scanner input = new Scanner(System.in); int n=input.nextInt(); //输入参数n if(n<1||n>1000){ System.out.println("无法识别,请输入1000以内的正整数"); }else{ System.out.println("创建成功!"); try { PrintStream ps = new PrintStream("../result.txt"); System.setOut(ps); }catch(Exception e){ System.out.println("文件创建失败"); } System.out.println("2016012026"+"\r\n"); //输出学号 for(int i=n;i<0;i--) { Lib.main(null); } } }
七.总结
由于Java基础不怎么好,长时间没有用的关系,写代码时仿佛是在重学,在编码时一直磕磕绊绊。之前的习惯不太好,每次写完代码都几乎不测试,只是简单的运行一下,在很多时候就直接跳过了。一些部分,比如控制生成算式中每一运算结果在一百以内没有很好做出,导致计算结果巨大,实际上不符合需求。这次测试时反反复复对代码进行修改纠错,结果还是不尽人意。在网上参考了各路网友的代码,可能是之前没好好学的原因,也不怎么看得懂。此次作业过后,我认为我应该加强自己的编码能力,重拾Java,多打代码,尽早摆脱啥都不会的窘境。
八.展示PSP
PSP2.1 | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
Planning | 计划 | 10 | 10 |
· Estimate | · 估计这个任务需要多少时间,并规划大致工作步骤 | 10 | 10 |
Development | 开发 | 315 | 688 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 60 |
· Design Spec | · 生成设计文档 | 5 | 8 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | 20 | 40 |
· Coding | · 具体编码 | 180 | 480 |
· Code Review | · 代码复审 | 30 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 40 | 60 |
Reporting | 报告 | 30 | 26 |
· Test Report | · 测试报告 | 10 | 8 |
· Size Measurement |
· 计算工作量 | 10 | 8 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 | 10 | 10 |