写到脑袋疼的结对作业1
211606350曾磊鑫 | | 211606364李冠锐
一、预估与实际
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 5 | 5 |
Development | 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 120 | 200 |
• Design Spec | • 生成设计文档 | 30 | 30 |
• Design Review | • 设计复审 | 40 | 80 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 80 | 110 |
• Design | • 具体设计 | 50 | 80 |
• Coding | • 具体编码 | 400 | 900 |
• Code Review | • 代码复审 | 100 | 150 |
• Test | • 测试(自我测试,修改代码,提交修改) | 120 | 200 |
Reporting | 报告 | 30 | 50 |
• Test Repor | • 测试报告 | 30 | 80 |
• Size Measurement | • 计算工作量 | 20 | 40 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 60 |
合计 | 1980 |
二、需求分析
我通过百度的方式了解到,小学三年级数学有如下的几个特点:
- 小学三年级的学生已经有能力做三到四个数字加减乘除的运算
- 学生们的算数能力依旧有限,依旧无法计算过于大的数字的加减乘除或者乘积过于大
经过分析,我认为,这个程序应当:
- 在原有的MathExamv1.0版本上加以优化,使其可以得出1,2,3年级的题目。
- 运用逆波兰算法得出式子的结果
三、设计
1. 设计思路
- 这个程序有一个类,八个方法(一个重构方法)
- 产生随机数字和两数运算时:
1.保证两个数字不超过50;
2.如果是加法运算的话,两个数字的和不超过100;
3.如果是减法运算的话,不应该产生结果为负数的式子;
2. 实现方案
写出具体实现的步骤
比如:
- 准备工作:.下载Git管理仓库,并在GitHub上fork亓老师主页的Pair2018_1仓库,并clone到本地;
- 技术关键点:
- Main(String str)将式子传入Arraylist;
- ReversePolishNotation()将原始式子转化为后缀形式(逆波兰)
- stack(String zf)将传入的字符传入存放字符的栈中
- judge(String str1, String str2)判断两个传入的字符的优先级哪个高
- count(String s1,String s2,String s3)主要用来计算
- count()用来计算遍历判断逆波兰式子的值是否为数字或字符,
并传到count(String s1,String s2,String s3)进行计算
四、编码
1. 调试日志
记录编码调试的日志,请记录下开发过程中的 debug 历程:
无法正确判断+-/()的优先级,以至于在后面无法正确把逆波兰式子算出结果;原因是自己在优先级判断的boolean judge(String str1, String str2没有正确将比较完的Boolean值传回ReversePolishNotation()方法中,后来添加了int Judge(String str)并且运用swtich()方法可以正确返回+-/()各个符号的优先级。
2. 关键代码
// 将中缀表达式转转化为逆波兰表达式
public void ReversePolishNotation() {
for (String str : list) {
if (str.matches("[0-9]+")) {
RPOlist.add(str);
}else if (str.matches("[\+\-\×\÷\(\)]")) {
stack(str);
}else {
System.out.println("非法表达式!");
}
}
while(!stack1.isEmpty()) {
RPOlist.add(stack1.pop());
}
}
// 创建一个用于存放字符的方法,将“+-×÷()”放进stack1中
public void stack(String zf) {
if (stack1.isEmpty()) { // 若为空栈,将字符存入栈中
stack1.push(zf);
return ;
}/*if ("(".equals(zf)){ // 判断字符是否为为“(”
stack1.push(zf);
return ;
}if (")".equals(zf)) { // 判断字符是否为为“)”
String string = "";
while(!"(".equals(string = stack1.pop())) {
RPOlist.add(string);
}return ;
}if ("(".equals(stack1.peek())) { // 若当前栈顶的元素为“(”,则直接入栈
stack1.push(zf);
return ;
}*/if (judge(zf,stack1.peek())) {// 判断优先级,若预存的字符优先级大于栈顶元素,将此字符存入栈中
stack1.push(zf);
return ;
}else{ // 若优先级低于栈顶元素,则将字符存入存逆波兰式子的数组中
RPOlist.add(stack1.pop());
stack(zf);
}
}
// 创建一个方法用来判断当前字符与栈顶元素的优先级,返回true或false
private boolean judge(String str1, String str2) {
return Judge(str1) > Judge(str2);
}
private int Judge(String str) {
switch(str) {
case "(" :return 3;
case "×" :
case "÷" :return 2;
case "+" :
case "-" :return 1;
case ")" :return 0;
default:return -1;
}
}
// 创建一个用来计算逆波兰式子结果的方法
public int count(String s1,String s2,String s3) {
int a = Integer.parseInt(s2);
int b = Integer.parseInt(s1);
switch(s3) {
case "+":
return a+b;
case "-":
return a-b;
case "×":
return a*b;
case "÷":
return a/b;
default :
return 0;
}
}
public int count() {
for (String str:RPOlist) {
if (str.matches("[0-9]+")) {
stack2.push(str);
}else {
stack2.push(String.valueOf(count(stack2.pop(),stack2.pop(),str)));
}
}
return Integer.parseInt(stack2.pop());
}
此段代码用于将随机产生的中缀算式式子转换为后缀形式(逆波兰),以便于计算。
3. 代码规范
-
第一条:方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵循驼峰形式:
public class mathExam {}
-
第二条:类名使用UpperCamelCase风格:
public class mathExam {}
-
第三条:左小括号和字符之间不出现空格;同样的,右小括号和字符之间也不出现空格:
if(stringArray.length > 2)
-
第四条 :
单行字符数限制不超过120个
-
第五条:任何二目、三木运算符的左右两边都需要加一个空格。
if(e == 2)
-
第六条:注释的双斜线与注释内容之间有且仅有一个空格。
// 单个参数输入则默认为一年级只需判断输入的数字是否异常
-
第七条: if/for/while/switch/do等保留字与括号之间都必须加空格。
if(e == 2)
-
第八条:左大括号后换行。
if(rd==1) { System.setOut(ps); System.out.println("("+i+")"+" "+b+" "+"+"+" "+c+" "+"="); d=b+c;list.add("("+i+")"+" "+b+" "+"+"+" "+c+" "+"="+" "+d); }
五、测试
由于我跟搭档能力都不是很足,暂时无法解决命令行输入和“-grade a -n b”形式的输入
输入 | 预期结果 | 实际结果 | 是否符合预期 |
---|---|---|---|
(一二年级的看个人作业1) | |||
5 3 | 输出5道三年级数学题 | 正确运行 | 是 |
10 3 | 输出10道三年级数学题 | 正确运行 | 是 |
六、总结
- 使用了“软件开发的基本策略:分而治之”,且需要重构;
- 结对让我们更能了解到对方的(真实)代码水平,让我们懂了什么叫菜鸡互啄;不过也好,菜鸡有菜鸡的好处毕竟压力不大,可以真正安静下来去分析要如何实现各种想法。
- 这次花费了更多的时间用于想如何实现用户用“-grade -n”的形式输入,想到后面实在想不下去了,就按 “分而治之” 策略,先将实现逆波兰式子的方法写出来;逆波兰这个新东西也是够磨人的啊,从看博客到自己画图到理解能稍微写出转化代码已经花了我两个下午了(这效率真的低得惊人)!将逆波兰式子算出结果又花了我一个半下午的时间....真是让人掉的头发...
- 周六迎新又没了一天时间,剩下的时间都只能用来调试还有继续优化代码,已经没有任何头绪去考虑输入格式还有其他的了...感觉又浪费了一周呢(完)