211606342杨艺勇 211606379王熙航

小学生计算

一、预估与实际

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 900 900
• Estimate • 估计这个任务需要多少时间 20 20
Development 开发 300 300
• Analysis • 需求分析 (包括学习新技术) 60 60
• Design Spec • 生成设计文档 30 30
• Design Review • 设计复审 10 10
• Coding Standard • 代码规范 (为目前的开发制定合适的规范) 10 10
• Design • 具体设计 120 180
• Coding • 具体编码 60 60
• Code Review • 代码复审 30 20
• Test • 测试(自我测试,修改代码,提交修改) 120 180
Reporting 报告 30 30
• Test Repor • 测试报告 30 30
• Size Measurement • 计算工作量 40 40
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 40 40
合计 900 1010

二、需求分析

三年级:

  • 出现小数加减法,参数至多两位
  • 乘法开始出现两位数乘以两位数的乘法
  • 除法要求除数至多为两位数,被除数最多为三位
    客户要求:
  • 运算符在2~4个
  • 可以加括号
  • 减法运算的结果不能有负数
  • 除法运算除数不能为0,不能有余数
  • 至少存在两个不相同的运算符

经过分析,我认为,这个程序应当:

  • 对一二年级的代码进行完善补全
  • 小数部分的题目忽略不计
  • 数字大小在1000以内,不存在负数
  • 舍弃含有余数的除法算数题

三、设计

1. 设计思路

  • 这个程序的关键就是能判断符号运算的优先级,并能判断括号的位置和括号起的限制作用
  • 随机产生的括号如果加在优先级高的运算符上就没有意义,需要单独列出

2. 实现方案

  • 运算符的个数可能是2,3,4个。分成3种情况分类随机生成符号以及数字并将其存入字符串中
  • 运算结果利用逆波兰算法求结果

四、编码

1. 调试日志

  • 一开始用循环随机来随机决定括号的位置,但是括号有时候会到算式的外面,后来是用来随机的数大了一位,导致括号外出

2. 关键代码

public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
sc.close();

StringBuilder sb = new StringBuilder(); //结果
Stack opStack = new Stack(); //运算符栈

Map<Character,Integer> opMap = new HashMap();   //运算符优先级
opMap.put('(', 0);
opMap.put('+', 1);
opMap.put('-', 1);
opMap.put('*', 2);
opMap.put('/', 2);

//处理字符串
for(int i=0;i<input.length();i++){
    if(input.charAt(i) == '('){             //如果是'('直接压栈
        opStack.push('(');
    }else if(isOperator(input.charAt(i))){  //如果是运算符
        char curOp = input.charAt(i);
        if(opStack.isEmpty())               //如果运算符栈是空,就直接压栈
            opStack.push(curOp);
        else if(opMap.get(curOp) > opMap.get(opStack.peek()))   //运算符栈不为空,且当当前运算符的优先级比站内第一个运算符的优先级高的时候,压栈
            opStack.push(curOp);
        else{                               //栈不为空,且运算符的优先级小于等于栈顶元素
            for(int j = 0;j<=opStack.size();j++){
                char ch = opStack.pop();    //弹出栈内第一个元素
                sb.append(ch + " ");
                if(opStack.isEmpty()){      
                    opStack.push(curOp);
                    break;
                }else if(opMap.get(curOp) > opMap.get(opStack.peek())){
                    opStack.push(curOp);
                    break;
                }
            }
        }
    }else if(input.charAt(i) == ')'){       //如果是')'就把站内'('上的元素都弹出栈
        for(int j = 0;j<opStack.size();j++){
            char c = opStack.pop();
            if(c == '(')
                break;
            else
                sb.append(c + " ");
        }
    }else{                                  //如果是数字就直接添加
        sb.append(input.charAt(i)+" ");
    }
}

//把栈内剩余的运算符都弹出站
for(int i = 0;i<=opStack.size();i++){
    sb.append(opStack.pop() + " ");
}

System.out.println(sb);

}

private static boolean isOperator(char charAt) {
// TODO Auto-generated method stub
if(charAt == '+'||charAt'-'||charAt'*'||charAt=='/')
return true;
return false;
}
采用逆波兰算法,计算算式的值

3. 代码规范

  • 代码中的命名均不能以下划线或美元符号开始,也不能一下划线或美元符号结束。

  • 代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。

  • 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵循驼峰形式。

  • 常量命名全部大写,单词键用下划线隔开,力求语义表达完整,不要嫌名字长。

  • 类型与中括号紧挨相连来定义数组。

  • POJO类中布尔类型的标量,都不要加is前缀,否则部分框架解析会引起序列化错误。

并人工检查代码是否符合规范

五、测试

  • 只输入一个参数100 结果 错误
  • 输入-n 10 -grade 1 结果正确
  • 输入1000 -n -grade 2 结果 输入格式错误
  • 输入-grade 3 -c 10 结果输入格式错误
  • 输入-n 10 -grade 002 结果正确

六、总结

结对编程,比一个人操作更体现学习能力;通过这次结对作业,自己觉得还是对这门课有很大的陌生感,深感自己的不足,代码不会写;不懂得问题关键出现在哪里,出现错误不会找出根源,还是希望在以后的学习过程中,加倍努力,多向班级里面的大佬们学习取经,既然选择了,就要坚持下去!

posted on 2018-09-19 11:09  Just丶dreams  阅读(119)  评论(0编辑  收藏  举报