211606356 陈宇 211606333温志铭
三年级学生的轻松代码
一、预估与实际
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 950 | 1260 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 60 | 80 |
• Analysis | • 需求分析 (包括学习新技术) | 120 | 180 |
• Design Spec | • 生成设计文档 | 30 | 45 |
• Design Review | • 设计复审 | 10 | 15 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
• Design | • 具体设计 | 40 | 60 |
• Coding | • 具体编码 | 300 | 500 |
• Code Review | • 代码复审 | 50 | 60 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 70 | 90 |
• Test Repor | • 测试报告 | 30 | 50 |
• Size Measurement | • 计算工作量 | 30 | 30 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1260 |
二、需求分析
我通过百度的方式了解到,小学三年级数学有如下的几个特点:
特点1:算式拥有多个运算符
- 特点2:算式包含括号
特点3:答案不能有余数
特点4:除数不能为0
经过分析,我认为,这个程序应当:
- 要让题目包含随机运算符个数和符号
- 要有随机的括号,让学生明白括号的优先级比乘除大
- 答案不存在余数
- 数字要大于0
- 除数不能为0
三、设计
1. 设计思路
- 这个程序需要在之前一二年级的基础上,增加一个三年级的出题方法
- 主类的作用是通过用户输入-n+数字 -grade+数字从而来判断要调用哪个方法来运行
- gradeThreee()这个方法需要先判断随机的运算符个数和运算符类型,再通过各种限制来实现加括号的功能
- 算式出来之后要运用逆波兰方法来实现算式的计算,从而得出答案
2. 实现方案
先有args[]长度判断用户输入的数据如不输入则默认输出100道3年级题名
- 通过gradeThree()方法生成三年级算式
- 通过网上查找学习逆波兰运算规则,用来求出算式答案
逆波兰参考网站:
这是类图
这是逆波兰说明图
四、编码
1. 调试日志
- 添加括号时出现(a+(b)+c)*d的情况,我添加了一个int数组flag标记括号的情况,默认为1,1为该数字有左括号,2右括号,只有为 0,1能添加左括号,1,2能添加右括号。
2. 关键代码
String[] str2 = new String[n1 + 1]; int[] flag = new int[n1 + 1];// 标记数组0(,1无符号,2) for (int j = 0; j < n1 + 1; j++) { flag[j] = 1; } int front = -2; String ss = null;// 用来保存一个算式,让它先为一个数字 for (int x = 0; x < n1; x++) { if (fuhao1[x].equals("+") || fuhao1[x].equals("-")) { int n2 = (int) (0 + Math.random() * (2 - 1 + 1));// 随机生成0或1,用来随机生成加减法的括号 boolean tag = false;// 用来标记是否括号成队 if (n2 == 0) { if (front == x - 1) {//如果前一个符号周围有括号 if ((flag[x - 1] == 1 || flag[x - 1] == 0) && flag[x - 1] != 2 && !tag) { str2[x - 1] = "(" + str2[x - 1]; flag[x - 1] = 0; } else { tag = true; } if ((flag[x + 1] == 1 || flag[x + 1] == 2) && flag[x + 1] != 0 && !tag) { str2[x + 1] = str2[x + 1] + ")"; flag[x + 1] = 2; } else { tag = true; } } else { if ((flag[x] == 1 || flag[x] == 0) && flag[x] != 2 && !tag) { str2[x] = "(" + str2[x]; flag[x] = 0; } else { tag = true; } if ((flag[x + 1] == 1 || flag[x + 1] == 2) && flag[x + 1] != 0 && !tag) { str2[x + 1] = str2[x + 1] + ")"; flag[x + 1] = 2; } else { tag = true; } front = x;// 标记当前符号位置 } } }
3. 代码规范
- 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
- 不允许任何未经定义的常量直接出现在代码中
- 在 if/else/for/while/do 语句中必须使用大括号。 即使只有一行代码,避免使用单行的形式
五、测试
- 输入参数-n 18.5 -grade 2 时 输出:请输入正数 !符合预期
- 输入参数-n 18 -grade 2.5时 输出:请输入正数 ! 符合预期
- 输入参数-n 18 时 输出:您输入的参数有误,请重新运行 ! 符合预期
- 输入参数-grade 2时 输出:您输入的参数有误,请重新运行 !!符合预期
- 输入参数-n 18 -grade 4时 输出:目前只支持1-3年级,请重新输入!符合预期
六、总结
请总结过程中的教训和经验,思考
- 这次做作业的过程中,了解了逆波兰算法,和调度场算法,明白了自己对栈的理解不够和数据结构的生疏,以后应该加强这方面的知识
- 学会了查看队友的代码,出现错误时如何复现过程如何debug