211606379王熙航 211606342 杨艺勇

MathExam V2.0

一、预估与实际

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 900 1010
• 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

二、需求分析

我通过客户提出需求的方式了解到,小学三年级数学有如下的几个特点:

  • 特点1
  • 运算符在2~4个
    可以加括号
    结果不能有负数
    除数不能为0,不能有余数

三、设计

1. 设计思路

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

2. 实现方案

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

四、编码

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<Character> 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 结果正确

六、总结

很多东西都还不会,写出的代码无法运行,不能熟练使用git,需要多加学习和练习。

posted @ 2018-09-19 10:49  嘿丶  阅读(204)  评论(1编辑  收藏  举报