作业概述
这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 个人项目作业 |
这个作业的目标 | 完成小学四则运算算法”的设计并进行测试 |
姓名学号 | 陈梓鹏 3121005208 |
项目链接
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 60 |
Estimate | · 估计这个任务需要多少时间 | 20 | 20 |
Development | 开发 | 60 | 90 |
Analysis | 需求分析 (包括学习新技术) | 60 | 90 |
Design Spec | 生成设计文档 | 15 | 20 |
Design Review | 设计复审 | 10 | 15 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
Design | 具体设计 | 60 | 70 |
Coding | 具体编码 | 120 | 150 |
Code Review | 代码复审 | 20 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 80 |
Reporting | 报告 | 30 | 40 |
Test Repor | 测试报告 | 20 | 25 |
Size Measurement | 计算工作量 | 20 | 15 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 575 | 755 |
性能分析
接口设计与实现
Create:
- select方法: 随机生成正数或真分数
- creatBackExp方法: 根据中缀表达式生成后缀表达式.通过表达式中序和后序遍历结果判断表达式是否相同
- 表达式可以看做一棵二叉树, 中缀表达式和后缀表达式就是对该二叉树的中序遍历和后续遍历后的结果
- create方法: 调用上面的两个方法, 生成不重复的表达式
IOFile:
- writeFile: 将字符串写入文件
- readFile: 以字符串形式读取文件
Reverse:
- 对Create传过来的表达式的中缀转化成后缀,遍历后缀表达式计算结果
- 中缀表达式转后缀表达式
public static String cal(String str) {
List<String> list = new ArrayList<>();
char[] arr = str.toCharArray();
//存放数字临时变量
StringBuffer tmpStr = new StringBuffer();
for (char c : arr) {
//如果是数字或小数点,添加到临时变量中
if (c>='0' && c<='9') {
tmpStr.append(c);
}
else if(c=='.') {
tmpStr.append(c);
}
//如果是加减乘除或者括号,将数字临时变量和运算符依次放入List中
else if (c=='+' || c=='-' || c=='*' || c=='/' || c=='(' || c==')'||c=='÷') {
if (tmpStr.length() > 0) {
list.add(tmpStr.toString());
tmpStr.setLength(0);
}
list.add(c + "");
}
else if (c==' ') {
continue;
}
}
if (tmpStr.length() > 0) {
list.add(tmpStr.toString());
}
//初始化后缀表达式
List<String> strList = new ArrayList<>();
//运算过程中,使用了两次栈结构,
//第一次是将中缀表达式转换成后缀表达式,第二次是计算后缀表达式的值
Stack<String> stack = new Stack<>();
//声明临时变量,存放栈元素
String tmp;
//将中缀表达式转换成后缀表达式
for (String s : list) {
//如果是左括号直接入栈
if (s.equals("(")) {
stack.push(s);
}
//如果是右括号,执行出栈操作,依次添加到后缀表达式中,直到出栈元素为左括号,左括号和右括号都不添加到后缀表达式中
else if (s.equals(")")) {
while (!(tmp = stack.pop()).equals("(")) {
strList.add(tmp);
}
}
//如果是加减乘除,弹出所遇优先级大于或等于该运算符的栈顶元素(栈中肯定没有右括号,认为左括号的优先级最低),然后将该运算符入栈
else if (s.equals("*") || s.equals("/")||s.equals("÷")) {
while(!stack.isEmpty()) {
//取出栈顶元素
tmp = stack.peek();//取出但不移除
if (tmp.equals("*") || tmp.equals("/")||tmp.equals("÷")) {
stack.pop();
strList.add(tmp);
}
else {
break;
}
}
stack.push(s);
}
else if (s.equals("+") || s.equals("-")) {
while(!stack.isEmpty()) {
//取出栈顶元素
tmp = stack.peek();
if (!tmp.equals("(")) {
stack.pop();
strList.add(tmp);
}
else {
break;
}
}
stack.push(s);
}
//如果是数字,直接添加到后缀表达式中
else {
strList.add(s);
}
}
//最后依次出栈,放入后缀表达式中
while (!stack.isEmpty()) {
strList.add(stack.pop());
}
main:
- 主类,调用create类生成表达式、Reverse类计算结果、IOFile类将表达式、比较结果输入到文件中
运行测试
-
通过命令行生成10道题目
-
生成的题目
-
自己的结果与输出的正确答案的对比
总结
- 通过对生成表达式和计算表达式的实现, 增强了对事件的抽象能力以及基本数据结构的熟悉程度,对二叉树的遍历,栈的调用有了进一步的理解