需求分析:
- 自然数:0, 1, 2, …。
- 真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
- 运算符:+, −, ×, ÷。
- 括号:(, )。
- 等号:=。
- 分隔符:空格(用于四则运算符和等号前后)。
- 算术表达式:
- e := n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),
其中e, e1和e2为表达式,n为自然数或真分数。 - 四则运算题目:e = ,其中e为算术表达式。
功能设计
功能:
1.生成随机数n
2.生成随机运算符
3.组成算数表达式
4.计算题目结果并输出文档
5.比较答案并给出错误题号
要求:
1.表达式不重复
2.结果无负数
3.结果最简,
4.算符不超过三个
程序设计
随机数表示,统一使用分数形式
类名:Num,参数类型:int,参数名:numerator(分子),denominator(分母)
- 功能点1:生成随机数
随机数生成方法:
//range为参数范围
public Num createNum(int range)
随机数约分方法:
public Num reduction(Num num)
- 功能点2:生成随机运算符
随机运算符生成方法:
public String createpOerator()
- 功能点3:组成算数表达式
表达式表示:
类型:ArrayList
组成方法:
public ArrayList<Object> createArithmetic(int range)
- 功能点4:计算表达式结果并输出文档
逆波兰式转换:
//list为生成的算数表达式
public ArrayList<Object> toRPN(ArrayList<Object> list)
逆波兰式计算
//right为逆波兰式
public Num countRPN(ArrayList<Object> right)
//计算两个数
private Num twoResult(String is, Num op1, Num op2)
文档输出:
//list1为题目集合,list2为答案集合
public void output(List<Object> list1, List<Object> list2)
- 功能点5:比较答案并记录错误题号
public void compare()
- 要求:
表达式不重复:
//list为刚生成的表达式
public boolean checkRPN(String list)
结果无负数:
//result为生成表达式的答案
public boolean checkAnswer(Num result)
工具类:
栈类:
类名:Stacks
参数:LinkedList list = new LinkedList();
int top = -1;
方法:
public void push(Object value)
public Object pop()
public Object top()
代码说明
//递归寻找最大公约数
public int getMaxDivisor(int numerator, int denominator) {
if (denominator == 0) {
return numerator;
} else {
return getMaxDivisor(denominator, numerator % denominator);
}
}
//三个运算符带括号生成方式
case 3:
// 括号开始位置
bracket_s = rand.nextInt(4);
// 括号结束位置
bracket_e = 0;
// 没有括号
if (bracket_s == 0) {
bracket_e = 0;
}
// 有括号
else {
bracket_e = bracket_s + rand.nextInt(2) + 1;
if (bracket_e >= 4) {
bracket_e = 4;
}
}
for (int i = 1; i <= 4; i++) {
//list为算数表达式
if (i == bracket_s) {
list.add("(");
}
list.add(f1.createNum(range));
if (i == bracket_e) {
list.add(")");
}
list.add(f2.createoperator());
}
list.remove(list.size() - 1);
break;
源代码已上传至Coding.net
codingd地址
https://coding.net/u/w2197525161/p/jisuan
测试运行
- 程序运行
- 选择操作数1
- 输入题目条件
- 文档位置
- 题目,答案与答题
- 测试答题
- 答案对照
PSP表格
因为是第一次使用PSP的方式统计程序开发时间,所以在估计时间与实际使用时间的统计上还有许多不清楚的地方。在没有刻意去计算时间的时候,常常忘记已经过了多久。
多数时间花费在程序实际上,虽然有参考部分思路,但还是采用了自己的设计思路,所以没有附上引用的博客链接。主要引用的是求最大公约数的递归算法,手机UC浏览器查到的,只是一张图片,具体链接不明。
心得
这个程序是在比较完善的设计思路下完成的,从数字的存储方式,到表达式的存储类型,到每一个功能点的设计,函数的构建有比较清晰的思路。较为困难的地方是具体方法的实现,可能是由于都是自己拍脑袋设计的方法,没有很好的去借鉴别人的经验,所以费了不少时间。
最后程序在表达式查重方面仅仅是使用了最简单的方法,由于是在想不出,在网上也找不到我认可的方式,所以暂时搁置。先发表一个版本以期后期完善。