小学四则运算“软件”之初版

作业要求地址:http://www.cnblogs.com/xiangxuer/p/9695909.html

github地址:https://github.com/1627851906/sizeyunsuan

1.个人软件过程耗时估计与统计表

PSP2.1 Personal Software Process Stages predicted(h) actual(h)
· Planning 计划 1 1
· Estimate 估计这个任务需要多少时间 8 10
· Development 开发 7 7
· Analysis 需求分析 (包括学习新技术) 1 0.5
· Design Spec 生成设计文档 1 1
· Design Review 设计复审 1 2
· Coding Standard 代码规范 1 1
· Design 具体设计 1 2
· Coding 具体编码 6 6
· Code Review 代码复审 7 9
· Test 测试(自我测试,修改代码,提交修改) 1 0.5
· Reporting 报告 1 1
· 测试报告 0.5 0.5
· 计算工作量 0.5 0.5
· 并提出过程改进计划 0.5 0.5

 

 

 

 

 

 

 

 

 

 

 

 

 

2.构思

因为是用java写的,所以想到用已经存在的Stack类来存放操作数和操作符,定义了两个Stack,一个存放Float类型,一个存放Character类型,用户决定出题数,但是每道题的操作数是随机出的,在这里写死了生成操作符的数目1~N,后期可以修改,只不过不想生成太长的式子,操作数就是操作符数目加一,后面如果出现乘号或除号后面出现加号或者减号,则添加括号,括号也压进操作符栈。然后事先定义一个算术符优先级表,进入一个循环,每次比较栈顶和次栈顶两个操作符的优先级,有‘<’, '>', '=',然后进行压栈入栈操作,最后操作符栈只剩下一个等于号并且操作数栈只剩一个操作数,即为整个式子答案。

3.设计

3.1、算术符优先级表

1  private static char[] signArray = new char[]{'+', '-', '×', '÷', '(', ')', '='};
2     private static char[][] signPriority = new char[][]{{'>', '>', '<', '<', '<', '>', '>'},
3             {'>', '>', '<', '<','<', '>', '>'}, {'>', '>', '>', '>', '<', '>', '>'}, {'>', '>', '>', '>', '<', '>', '>'},
4             {'<', '<', '<', '<','<', '=', ' '}, {'>', '>', '>', '>', '>', '>', ' '}};

3.2、计算式子答案方法

private static Float getResult(Stack<Float> operatedNumber, Stack<Character> operatedSign) {
        int count = 0, flag=1;
        Stack<Float> tempNumber = new Stack<Float>();
        Stack<Character> tempSign = new Stack<Character>();
        Float newData = null, numberTop = null, numberNext = null, numberNextNext = null;
        Character signTop = null, signNext = null;
        while (operatedNumber.size() != 1 && operatedSign.size() != 1) {
            switch (signPriority[getPosition(operatedSign.get(operatedSign.size() - 1))][getPosition(operatedSign.get(operatedSign.size() - 2))]) {
                case '>':
                    numberTop = operatedNumber.pop();
                    numberNext = operatedNumber.pop();
                    signTop = operatedSign.pop();
                    newData = calculate(numberTop, signTop, numberNext);
                    operatedNumber.push(newData);
                    break;
                case '<':
                    numberTop = operatedNumber.pop();
                    numberNext = operatedNumber.pop();
                    numberNextNext = operatedNumber.pop();
                    signTop = operatedSign.pop();
                    signNext = operatedSign.pop();
                    if (!operatedSign.isEmpty()&& (signNext == '(' || operatedSign.get(operatedSign.size()-1)=='(')) {
                        if (operatedSign.get(operatedSign.size()-1)=='(') {
                            operatedSign.pop();
                            operatedNumber.push(numberNextNext);
                            flag=0;
                        }
                        else {
                            operatedNumber.add(numberNextNext);
                            operatedNumber.add(numberNext);
                        }
                        while(operatedSign.get(operatedSign.size()-1)!=')') {
                            tempSign.add(operatedSign.pop());
                            count++;
                        }
                        tempSign.push('=');
                        for (int i =0; i<count+1; i++) {
                            tempNumber.add(operatedNumber.pop());
                        }
                        tempNumber = setNumberReserve(tempNumber);
                        tempSign = setSignReserve(tempSign);
                        if (flag==1) {
                            newData = calculate(numberTop, signTop, getResult(tempNumber,tempSign));
                            operatedNumber.push(newData);
                        }
                        else {
                            newData = calculate(numberNext, signNext, getResult(tempNumber,tempSign));
                            operatedNumber.push(newData);
                            operatedNumber.push(numberTop);
                            operatedSign.push(signTop);
                        }
                    }
                    else {
                        newData = calculate(numberNext, signNext, numberNextNext);
                        operatedSign.push(signTop);
                        operatedNumber.push(newData);
                        operatedNumber.push(numberTop);
                    }
                    break;
                case '=':
                    operatedSign.pop();
                    operatedSign.pop();
                    break;
                default:
                    break;
            }
        }
        return operatedNumber.get(0);
    }

  

4.遇到的问题

1.某些式子算出的答案会出现负数,不符合题目要求;

解决方法;1.重新生成一个不是负数的式子,方法不太好,但是比较简单。2.避免减法出现的负数,但是由于是先生成式子,在进行计算,有一些比较长的式子,如100÷50+3-2等之类的的式子,避免负数的出现比较麻烦,因为负数不是直接因为3-2生成的。

2.计算结果的答案不正确;

入栈出栈没设计好,逻辑不够清晰,经过代码调试,解决问题。

3.生成分数的控制

分数约分问题,有点麻烦,暂时没解决。

 

猜你喜欢

转载自www.cnblogs.com/-QAQ/p/9765576.html
今日推荐