作业MathExamV2.0
MathExam233
211614269 林凯 211601233张康凌
一、预估与实际
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| Planning | 计划 | ||
| • Estimate | • 估计这个任务需要多少时间 | 20 | 30 | 
| Development | 开发 | ||
| • Analysis | • 需求分析 (包括学习新技术) | 60 | 240 | 
| • Design Spec | • 生成设计文档 | 20 | 40 | 
| • Design Review | • 设计复审 | 5 | 5 | 
| • Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 10 | 
| • Design | • 具体设计 | 20 | 40 | 
| • Coding | • 具体编码 | 120 | 990 | 
| • Code Review | • 代码复审 | 30 | 20 | 
| • Test | • 测试(自我测试,修改代码,提交修改) | 60 | 300 | 
| Reporting | 报告 | ||
| • Test Repor | • 测试报告 | 60 | 70 | 
| • Size Measurement | • 计算工作量 | 5 | 5 | 
| • Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 10 | 10 | 
| 合计 | 450 | 1800 | 
二、需求分析
我通过上网调查的方式了解到,这次任务有如下的几个特点:
- 小学一年级
- 使用的数字必须小于100
 - 减法方面得出的结果必须为正整数
2.小学二年级 - 在乘法方面两个数满足乘法口诀表,小于10
 - 在除法方面,被除数小于90,商和除数还有余数必须为个位数。
 - 乘除法得出的结果为正数
 
 - 小学三年级
- 运算符在2~4个
 - 可以加括号
 - 减法运算的结果不能出现负数
 - 除法运算 必须为整除 而且除数不能为0
 
 
三、设计
1. 设计思路

- 这个程序有两个类
- 主函数负责判断传入参数是否合法,并根据相应参数调用相应方法
 - calculate类专门用来计算表达式的结果
 
 - 算法的关键是什么?
 - 调度场算法
- 定义两个栈,一个栈叫做保存运算符记为op,另一个栈保存最终的表达式记为rpn。
 - 数字直接入op栈
 - op栈顶若是(则无条件入栈
 - 运算符要与op栈顶比较,优先级大则入栈,小于或等于则op出栈后再入栈
 
 - 逆波兰式求值
- 定义一个栈
 - 从左到右扫描逆波兰式
 - 读到一个数字时就将它压入栈中
 - 读到一个运算符时,就从栈中弹出两个数字,并将该运算符作用于这两个数字,然后将计算结果再压入栈中
 - 逆波兰式读取完毕时,栈中剩下的就是最终结果
 
 - 生成合适的随机数
- (int) (min + Math.random() * (max - min + 1)) 可生成min-max范围内的数;
 
 
2. 实现方案
- 准备工作:先在github上创建仓库,克隆到本地。
- 重要关键点:逆波兰式的理解以及应用
四、编码
1. 调试日志
-在代码的什么位置,代码出现了什么问题,问题会导致什么结果,怎么解决的
-在使用调度场算法将题目转换成逆波兰式时出现了问题,因为题目的数字可能是个位也可能是两位,直接通过下标截取字符串的方法明显不合适。最后我决定写一个方法,将题目中的符号及数值按顺序存放至字符串数组中,使用的时候遍历数组取出即可。
-在出题时,有可能出现除法有余数的情况,导致题目不符合要求。我的做法是在生成除号时,将前一个被除数取出,同时随机出被除数,若不能整除,则一直循环随机出被除数,最后一定能保证不会有余数。
2. 关键代码
public class Calculate {
	// 构造方法传入题目
	public static int ans(String str) {
		// TODO Auto-generated constructor stub
		squestion = str;
		cutStr();
		reversePolishNotation();
		return compute();
	}
	// 题目的字符串
	public static int slen;
	public static String[] scut = new String[100];
	public static String squestion;
	// 存操作符的栈
	public static Stack<String> soperators = new Stack<>();
	// 存放转换后的逆波兰式
	public static Stack<String> srpn = new Stack<>();
	// 用于调换逆波兰式的顺序
	public static Stack<String> srpnb = new Stack<>();
	// 计算逆波兰式用的栈
	public static Stack<String> cal = new Stack<>();
	public static boolean isNum(String str) {
		for (int i = 0; i < str.length(); i++) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}
	// 将字符串的题目切割成数值和符号
	public static void cutStr() {
		int n = 0;
		String str=squestion.replaceAll(" ", "");
		squestion=str;
		for (int i = 0; i < squestion.length(); i++) {
			if (Character.isDigit(squestion.charAt(i))) {
				if ((i + 1) < squestion.length() && Character.isDigit(squestion.charAt(i + 1))) {
					int num = (squestion.charAt(i) - '0') * 10 + (squestion.charAt(i + 1) - '0');
					scut[n] = String.valueOf(num);
					n++;
					i++;
				} else if (squestion.charAt(i) == ' ') {
				} else {
					int num = squestion.charAt(i) - '0';
					scut[n] = String.valueOf(num);
					n++;
				}
			} else {
				scut[n] = String.valueOf(squestion.charAt(i));
				n++;
			}
		}
		slen = n;
	}
	public static int priority(String str) {
		switch (str) {
		case "(":
			return 0;
		case "+":
		case "-":
			return 1;
		case "*":
		case "/":
			return 2;
		default:
			return -1;
		}
	}
	// 转换成逆波兰式
	public static void reversePolishNotation() {
		for (int i = 0; i < slen; i++) {
			if (!(scut[i].equals("+") || scut[i].equals("-") || scut[i].equals("*") || scut[i].equals("/") || scut[i].equals("(") ||  scut[i].equals(")"))) {
				srpn.push(scut[i]);
			} else {
				if (soperators.isEmpty() || scut[i].equals("(")) {
					soperators.push(scut[i]);
				} else {
					if (priority(scut[i]) > priority(soperators.peek())) {
						soperators.push(scut[i]);
					} else {
						if(scut[i].equals(")")) {
							while (!soperators.peek().equals("(")) {
								srpn.push(soperators.pop());
							}
							soperators.pop();
						}else {
							while ((!soperators.isEmpty()) && (priority(soperators.peek()) >= priority(scut[i]))) {
								srpn.push(soperators.pop());
							}
							soperators.push(scut[i]);
						}
					}
				}
			}
		}
		while (!soperators.isEmpty()) {
			srpn.push(soperators.pop());
		}
	}
	public static int compute() {
		// 倒换逆波兰式顺序
		while (!srpn.isEmpty()) {
			srpnb.push(srpn.pop());
		}
		while (!srpnb.isEmpty()) {
			if (srpnb.peek().equals("+") || srpnb.peek().equals("-") || srpnb.peek().equals("*")
					|| srpnb.peek().equals("/")) {
				String sym = srpnb.pop();
				int a = Integer.parseInt(cal.pop());
				int b = Integer.parseInt(cal.pop());
				if (sym.equals("+")) {
					cal.push(String.valueOf(b + a));
				} else if (sym.equals("-")) {
					cal.push(String.valueOf(b - a));
				} else if (sym.equals("*")) {
					cal.push(String.valueOf(b * a));
				} else {
					cal.push(String.valueOf(b / a));
				}
			} else {
				cal.push(srpnb.pop());
			}
		}
		return Integer.parseInt(cal.pop());
	}
}
3. 代码规范
请给出本次实验使用的代码规范:
- 在for循环/do while/if等语句必须加括号以及字与括号间的空格
 - 在if里嵌套多个if 要对应好if 与else 防止出错
 - 一般情况下使用空格缩进
 - 在括号方面在结束的时候必须换行,左边大括号后面要换行,右边大括号换行
 - 不能使用未定义的变量

 
五、测试
| 测试输入 | 输出 | 是否符合预期效果 | |
| -n 100 -grade 1 | 执行成功 | 是 | |
| -n 100 -grade 2 | 执行成功 | 是 | |
| -n 100 -grade 3 | 执行成功 | 是 | |
| -grade 1 -n 100 | 执行成功 | 是 | |
| -grade 2 -n 100 | 执行成功 | 是 | |
| -grade 3 -n 100 | 执行成功 | 是 | |
| 不输入任何参数 | 输入错误 | 是 | |
| 输入一个参数:20 | 输入错误 | 是 | |
| -n 20 | 输入错误 | 是 | 
六、总结
这次的任务真的太难了,耗费的时间太多了。	很多内容都需要上网查找思路,经过这次的任务让我感到更加没有头绪 的怎么去面对去学习代码去适应,感觉自己还是需要更深的去理解和实践代码。


作业MathExamV2.0的更多相关文章
- MathExamV2.0四则混合运算计算题生成器
		
MathExamV2.0四则混合运算计算题生成器----211606360 丁培晖 211606343 杨宇潇 一.预估与实际 PSP2.1 Personal Software Process Sta ...
 - 【作业4.0】HansBug的第四次面向对象课程思考
		
嘛..不知不觉这门课程要结束了,那么就再说点啥以示庆祝呗. 测试vs正确性论证 说到这个,相比很多人对此其实很有疑惑,请让我慢慢分析. 逻辑概览 首先我们来看看两种方式各自的做法和流程是什么样的: 单 ...
 - 2018上C语言程序设计(高级)作业- 第0次作业
		
准备工作(10分) 1.在博客园申请个人博客. 2.加入班级博客(2班班级博客链接地址)(1班班级博客链接地址) 3.关注邹欣老师博客.关注任课老师博客. 4.加入讨论小组,学习过程中遇到问题不要随意 ...
 - 【作业2.0】HansBug的5-7次OO作业分析与小结,以及一些个人体会
		
不知不觉又做了三次作业,容我在本文胡言乱语几句2333. 第五次作业 第五次作业是前面的电梯作业的多线程版本,难度也有了一些提升.(点击就送指导书) 类图 程序的类图结构如下: UML时序图 程序的逻 ...
 - 小学生作业V2.0
		
211606320刘佳&211506332熊哲琛 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Plann ...
 - 【作业1.0】OO第一单元作业总结
		
OO第一单元作业已全部完成,为了使这一单元的作业能够收获更多一点,我回忆起我曾经在计算机组成课设中,经常我们会写一些实验报告,经常以此对实验内容反思总结.在我们开始下一单元的作业之前,我在此对OO第一 ...
 - 【作业3.0】HansBug的第三次博客规格总结
		
转眼间第三次作业了,似乎需要说点啥,那就说点. 规格&工业 说到这个,不得不提一下软件开发的发展史. 历史的进程 早在上世纪50年代,就已经有早期的编程语言出现,也开始有一些程序编写者出现(多 ...
 - C语言--第1次作业2.0版
		
1.本章学习总结 1.1思维导图 1.2本章学习体会及代码量学习体会 1.2.1学习体会 经过一周C语言的正式课堂学习,不同于暑期时扒视频囫囵吞枣式学习,林丽老师的讲解详细异常,尽管已经学习了一部分内 ...
 - 2018上IEC计算机高级语言(C)作业 第0次作业
		
最理想的师生关系是健身教练和学员的关系,在这种师生关系中你期望获得来自老师的哪些帮助? 最理想的的师生关系是健身教练和学员的关系,其实我个人感觉不太认同,我觉得老师和学生之间更多的是一种共生关系,像植 ...
 
随机推荐
- 在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all
			
在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all 前天来了个新需求, 有一个授权书的文件要点击下载, 需要在前端生成, ...
 - Flash的swf文件破解
			
1.准备好flash文件,xxx.swf(后缀为swf),将其重构swf文件为fla源文件. 2.asv软件(5以上版本)的操作 1.点击左上角 文件 --> 打开 --> 运行已准备好的 ...
 - AttributeError: module 'tensorflow' has no attribute 'enable_eager_execution'
			
Traceback (most recent call last): File "linear_regression_eager_api.py", line 15, in < ...
 - stm32按键FIFO的实现
			
学习目标: 1.理解FIFO的基本概念和设计按键FIFO的意义 2.写出实现按键FIFO的代码 1.设计按键FIFO的优点 要介绍实现按键FIFO的优点,首先要了解FIFO的一些基本概念.FIFO ...
 - python3配置文件的增删改查,记录一下
			
#!/usr/bin/env python3 import json #json模块,用于将像字典的字符串转换为字典 import re #re模块,查找替换 import shutil #copy文 ...
 - DotNetty学习笔记
			
DotNetty项目本身的示例很容易运行起来,但是具体到真实的应用场景,还是需要进一步理解DotNetty的通道处理细节,这样才能够在实际项目应用中处理具体的问题. 简单的场景下会有以下几个问题,第一 ...
 - 20155330 2016-2017-2 《Java程序设计》第九周学习总结
			
20155330 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 学习目标 了解JDBC架构 掌握JDBC架构 掌握反射与ClassLoader 了解自定义泛 ...
 - Centos安装man功能
			
CentOS接触很久了,但是一直作为服务器端使用.这次之所以安装man,是由于开始学习Nginx了. 言归正传,安装man,首先得下载包.由于我们天朝的原因,代码包几乎下不到的.首先你得FQ,再下载, ...
 - 1111: [POI2007]四进制的天平Wag
			
1111: [POI2007]四进制的天平Wag 链接 题意: 用一些四进制数,相减得到给定的数,四进制数的数量应该尽量少,满足最少的条件下,求方案数. 分析: 这道题拖了好久啊. 参考Claris的 ...
 - LVS入门篇(四)之LVS实战
			
一.LVS的NAT模式实战 1.环境说明: HOST OS role remask 192.168.56.12 Centos 7.4 LVS调度器(1.2.7) VIP:192.168.0.104 1 ...