各类的功能说明如下:
1、Test.java
该类是程序运行入口类,主要功能为调用其他功能模块按要求完成出题,批改,查重等过程
2、DataOper.java
该类主要完成整数与假分数,带分数之间的运算和比较以及格式化问题,并调用其他功能完成问题的查重与
作业的修改问题
3、Expression.java
该类主要用来保存表达式相关的信息,比如表达式的字符串表达与答案
4、GetExpression.java
该类调用其他功能模块,完成表达式的规范化,并且计算出表达式的值
5、Grade.java
该类用来保存成绩的相关信息
6、OperExpression.java
该类用来处理初步拼合而成的表达式,使其满足作业要求,并将初步的表达式统一规范化,便于以后的查重处理
7、ProExpression.java
该类主要用来产生初步拼合而成的表达式
查重思路的实现:
1、制定优化二叉树的策略,以达到将表达式规范化的目的,当表达式规范后,重复的表达式将以“同一面目”出现,我们之后就可以直接根据字符串的比较判断两个表达式是否相同。
优化策略如下:
(1)如果右子树的值大于左子树,则左右左子树互换,这样可以保证运算中不会出现负数。
(2)不管左右子树的运算符优先级如何,凡左右子树的根节点为运算符的,在生成表达式时统一在两边加上括号。
如图所示的二叉树,将生成:(1+3)-(1*2)
如:1+2+3,3+(1+2)的两个表达式,规范化后都会变为(1+2)+3,此时我们只需进行字符串比较即可判断题目是否重复
代码说明:
1、
/*
* 按规则优化二叉树,使其计算过程中不出现负数,并且中序遍历,生成查重使用的表达式,进行查重处理
* 按照二叉树求值
*
*/
public BinaryTree adjustmentTree(BinaryTree t) {
if(t!=null) {
String left_value =getTree_value(t.getLeft_tree());
String right_value = getTree_value(t.getRight_tree());
//若右子树的值大于左子树,则交换子树
if(right_value.equals("")||left_value.equals("")) {
return t;
}
else if(dataOper.operData(right_value, left_value,"?").equals("1")) {
t=swapChildTree(t);
}
t.setLeft_tree(adjustmentTree(t.getLeft_tree()));
t.setRight_tree(adjustmentTree(t.getRight_tree()));
}
return t;
}
//中序遍历二叉树,转化为符合预定运算顺序的带括号的表达式
public String treeToExpression(BinaryTree t) {
String left_s="";
String right_s="";
String expression="";
if(t!=null) {
if(t.getLeft_tree()!=null&&t.getRight_tree()!=null) {
String left_root=t.getLeft_tree().getRoot_data();
String right_root=t.getRight_tree().getRoot_data();
if(left_root.equals("+")||left_root.equals("-")||left_root.equals("*")||left_root.equals("÷")) {
left_s="("+treeToExpression(t.getLeft_tree())+")";
}
else {
left_s=treeToExpression(t.getLeft_tree());
}
if(right_root.equals("+")||right_root.equals("-")||right_root.equals("*")||right_root.equals("÷")) {
right_s="("+treeToExpression(t.getRight_tree())+")";
}
else {
right_s=treeToExpression(t.getRight_tree());
}
}
expression=left_s + t.getRoot_data() + right_s;
}
return expression;
}
2、
//由随机生成的基本表达式的后缀表达式按要求构建二叉树
public BinaryTree OptiExpression(String expression) {
Stack<String> stack = new Stack<String>();
Stack<BinaryTree> tstack = new Stack<BinaryTree>();
BinaryTree bt = new BinaryTree();
char []express = expression.toCharArray();
String s = "";//暂存入栈信息
for(int i=0;i<express.length;i++) {
if(express[i]!='+'&&express[i]!='-'&&express[i]!='*'&&express[i]!='÷'&&express[i]!='#') {
s+=express[i];
}
else if(express[i]=='#'){
if(!s.equals("")) {
BinaryTree t = new BinaryTree();
t.setRoot_data(s);
t.setLeft_tree(null);
t.setRight_tree(null);
tstack.push(t);
bt=t;
}
s="";
}
else if(express[i]=='+'||express[i]=='-'||express[i]=='*'||express[i]=='÷') {
if(!s.equals("")) {
BinaryTree t = new BinaryTree();
t.setRoot_data(s);
t.setLeft_tree(null);
t.setRight_tree(null);
tstack.push(t);
bt=t;
}
s=""+express[i];
//System.out.println("zan"+tstack.size());
BinaryTree t1 = new BinaryTree();
t1.setRoot_data(s);
t1.setRight_tree(tstack.pop());
t1.setLeft_tree(tstack.pop());
tstack.push(t1);
s="";
bt=t1;
}
}
return bt;
}
五、测试运行
六、PSD统计:
PSP2.1 |
Personal Software Process Stages |
Time Senior Student |
Time |
|
Planning |
计划 |
45 |
60 |
|
· Estimate |
估计这个任务需要多少时间 |
800 |
900 |
|
Development |
开发 |
600 |
650 |
|
· Analysis |
需求分析 (包括学习新技术) |
20 |
15 |
|
· Design Spec |
生成设计文档 |
30 |
40 |
|
· Design Review |
设计复审 |
10 |
10 |
|
· Coding Standard |
代码规范 |
10 |
10 |
|
· Design |
具体设计 |
20 |
15 |
|
· Coding |
具体编码 |
600 |
800 |
|
· Code Review |
代码复审 |
10 |
10 |
|
· Test |
测试(自我测试,修改代码,提交修改) |
20 |
30 |
|
Reporting |
报告 |
30 |
60 |
|
· |
测试报告 |
10 |
10 |
|
· |
计算工作量 |
10 |
10 |
|
· |
并提出过程改进计划 |
5 |
5 |
|
|
|
|
|
|
七、小结
由于最近开发任务有点多,所以一直到近两天才开始研究这个作业。之前看过一些二叉树实现查重的思路,但是我觉得太繁杂了,于是后来就想到我以上描述的那种方法进行查重。虽然括号会显得过多和冗余了,但是对于题目的查重却很容易实现,个人觉得这个方法还是不错的。这个题目看似其貌不扬,然后做起来却发现要处理的小问题非常的多,比如当数值如真分数,带分数和整数以字符串形式出现时,要想办法完成他们之间的计算,大小比较,还有格式互换等功能,工作真的很繁重。另外中缀表达式转为后缀表达式也有一定的难度,二叉树的生成和优化,以及利用二叉树对表达式进行求值时,用到了大量的递归思维,bug很多,调试了很久,才达到自己想要的目的。总的来说,这样一个小小的项目,收获也还是蛮多的,期待接下来将其改进,做得更好一些。
八、源代码
源代码已提交至码云仓库:https://gitee.com/zhanglingchao/FourOperation
来源:oschina
链接:https://my.oschina.net/u/4382879/blog/4025250