四则运算器(带括号和分数)的Java实现
一 psp 表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 8 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 8 |
Development | 开发 | 655 | 785 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 35 |
· Design Spec | · 生成设计文档 | 30 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 10 | 15 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 5 | 5 |
· Design | · 具体设计 | 40 | 60 |
· Coding | · 具体编码 | 5h*60 | 12h*60 |
· Code Review | · 代码复审 | 1h*60 | 1.5h*60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 3h*60 | 2h*60 |
Reporting | 报告 | 290 | 330 |
· Test Report | · 测试报告+博客 | 4h*60 | 4.5h*60 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 40 | 50 |
合计 | 955 | 1123 |
二 项目要求
1.小学四则运算题目,结果不能出现负数
2.支持真分数运算
3.支持带括号的多元复合运算
4.批量生成,可选择运算符,可选择数字范围,可选择数字个数
三 解题思路
1.列出随机的四则运算表达式 (表达式添加有意义的括号)
2.根据表达式得出正确结果
3.关于真分数,可以在最后把÷转换成/
四 解决
1. 生成表达式
1. 如何添加有意义括号(如何判断有意义?)
2. 分母为0无意义
参考
https://github.com/wapleeeeee/Arithmetic-operation/blob/master/homework2.py
https://blog.csdn.net/weixin_30822451/article/details/98153506
坑1:使用String的超过10的话 10被当作两个字符,插入括号时候出问题
坑2: 1/2/3 这种式子的出现
2.计算表达式
1. 如何支持真分数运算?
2. 中缀表达式 转 后缀表达式
3. 计算表达式 (数据结构的使用)
参考
https://github.com/kiprobinson/BigFraction
https://www.cnblogs.com/menglong1108/p/11619896.html
https://zhuanlan.zhihu.com/p/150684393
真分数出现 55/1 需要对/1进行去除
String answer = stack.pop();
if (answer.substring(answer.length()-2).equals("/1")){
return answer.substring(0,answer.length()-2);
五 具体程序设计
1.总体设计
2.具体程序设计
1.Equation类
类Equation用于保存每一个表达式的属性
成员变量
变量名 | 类型 | 功能 |
---|---|---|
equz | String | 中缀表达式 |
equh | String | 后缀表达式 |
answer | String | 表达式值 |
成员方法 | ||
函数名 | 输入 | 输出 |
---- | ---- | ---- |
setEquz | String equ | |
setEquh | String equ | |
getEquzAnswer | String equ | String answer |
getEquhAnswer | String equ | String answer |
2.Utils类
类Utils用于生成表达式已经计算表达式,添加括号等功能
成员变量
变量名 | 类型 | 功能 |
---|---|---|
op | list | 保存运算符 |
成员方法
函数名 | 输入 | 输出 | 依赖函数 | 功能 |
---|---|---|---|---|
getRglEquation | int num,start,end | String equ | 生成无括号表达式 | |
insertBracke | String equ | String equ | 为无括号表达式插入括号 | |
epuToList | String equ | List equ | 表达式转换为列表 | |
getBrcEquation | int num,start,end | String equ | insertBracke | 生成有括号表达式 |
parseSuffixExpressionList | List equ | List equ | 中缀转后缀 | |
calculat | List equ | String answer | BigFraction | 计算表达式的值 |
六 重点代码说明
运行结果
七 单元测试
1.测试函数均通过
2.具体测试
1. getRglEquation函数
测试函数如下 获取无括号表达式
public void getRglEquation() {
int num; // 随机2-7个数字生成
int start = 1;
int end = 9;
String str;
for (int i = 0; i < 1000000; i++) {
num = (int) (Math.random() * 5) + 2;
str = utils.getRglEquation(num, start, end);
}
}
测试了100W次随机生成的不带括号字符串,用时500ms。
2. getBrcEquation函数
测试函数如下 获取有括号表达式
public void getBrcEquation() {
int num; // 随机2-7个数字生成
int start = 1;
int end = 9;
String str;
for (int i = 0; i < 1000000; i++) {
num = (int) (Math.random() * 5) + 2;
str = utils.getBrcEquation(num, start, end);
}
}
测试了100W次随机生成的带括号字符串,用时777ms。
3. calculate函数
测试函数如下 计算后缀表达式
public void calculate() {
int num; // 随机2-7个数字生成
int start = 1;
int end = 9;
String str;
for (int i = 0; i < 1000000; i++) {
num = (int) (Math.random() * 5) + 2;
str = utils.getBrcEquation(num, start, end);
List list1 = utils.epuToList(str);
List list2 = utils.parseSuffixExpressionList(list1);
String answer = utils.calculate(list2);
}
}
测试了100W次随机生成的带括号字符串,用时7s。
八 效能分析与改进
九 代码更新
坑1: list toString 会把[] 空格 ,算进字符串
解决:添加一个方法去除 listToString中的[],空格
public String toSimpleStr(List<String> equ) {
return equ.toString().replaceAll("(?:\\[|,|null|\\]| +)", "");
}