结对项目:简易实现自动生成四则运算

发布时间 2023-09-29 01:12:38作者: 2021计科2班许志楷
作业所属课程 计科21级12班软件工程
作业要求 结对项目:简易实现自动生成四则运算
作业链接 结对项目
作业目标 实现论文查重,并优化代码,提高性能

Github链接

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

具体实现

实现流程

1.生成表达式(中缀表达式)包含不超过三个的运算符
2.将中缀表达式转化为逆波兰表达式
3.计算
3.1如果都为整数,正常计算
3.2如果有分数,先通分,再计算,最后约分
4.返回符合格式的答案并写入文件

具体实现类

generateFormula类负责生成表达式
Calculate类完成主要的计算
main是入口

生成表达式关键代码

 public static String finalFormulation() {
        String formula = new String();
        Random random = new Random();
        int numberOfOperation=random.nextInt(OperationNum)+1;
        if (numberOfOperation==1)
        {
            formula+=getRandomNumber()+" "+getRandomOperator()+" "+getRandomNumber();
            return formula;
        }
        int ifHavaBracket = random.nextInt(2);
        if (ifHavaBracket==1)
        //没有括号
        {
            formula+=getRandomNumber();
            while (numberOfOperation!=0)
            {
                formula+=" "+getRandomOperator();
                formula+=" "+getRandomNumber();
                numberOfOperation--;
            }
        } else if (numberOfOperation==2)
        {
            Random random1 = new Random();
            int bracketLocation = random1.nextInt(numberOfOperation);
            if (bracketLocation==1)
            {
                formula+=BRACKET[0];
                formula+=" "+getRandomNumber();
                formula+=" "+getRandomOperator();
                formula+=" "+getRandomNumber();
                formula+=" "+BRACKET[1];
                formula+=" "+getRandomOperator();
                formula+=" "+getRandomNumber();
            } else
            {
                formula+=getRandomNumber();
                formula+=" "+getRandomOperator();
                formula+=" "+BRACKET[0];
                formula+=" "+getRandomNumber();
                formula+=" "+getRandomOperator();
                formula+=" "+getRandomNumber();
                formula+=" "+BRACKET[1];
            }
        } else {
            formula+=getRandomNumber();
            formula+=" "+getRandomOperator();
            formula+=" "+getRandomNumber();
            formula+=" "+getRandomOperator();
            formula+=" "+getRandomNumber();
            formula+=" "+getRandomOperator();
            formula+=" "+getRandomNumber();
        }
        return formula;
    }

计算类的关键代码

 //后缀表达式的计算
    public static String processCalculate(List<String> list) {
        Stack<String> number = new Stack<>();
        int index = 0;
        for (String item : list) {
            //如果是多位数字
            if (isNumber(item)) {
                number.push(item);
                //如果是运算符
            } else {
                String num1 = number.pop();
                String num2 = number.pop();
                String res = calculate(num1, num2, item);
                number.push(res);
            }
        }
        return number.pop();
    }
 //中缀表达式转后缀表达式
    public static List<String> InfixToSufferFixExpression(List<String> infixExpression)
    {
        Stack<String> stack1 = new Stack<>(); //符号栈
        List<String> stack2 =new ArrayList<String>();
        //遍历中缀表达式的各个字符
        for (String s : infixExpression) {
            //遇到操作数是
            if (isNumber(s))
                stack2.add(s);
            else if (s.equals("("))
                stack1.push(s);
            else if (s.equals(")"))
            {
                String pop=stack1.pop();
                while (!pop.equals("("))
                {
                    stack2.add(pop);
                    pop=stack1.pop();
                }
            } else //遇到运算符时
            {
                int value = Operation.getValue(s);
                while (stack1.size()!=0 && value<Operation.getValue(stack1.peek()))
                {
                    stack2.add(stack1.pop());
                }
                stack1.push(s);
            }
        }
        while (stack1.size()!=0) {
            stack2.add(stack1.pop());
        }
        return stack2;
    }

结果

代码覆盖率

项目总结
这次的项目还有一些部分没有完成,如解决重复表达式,增加负数的可能性去增强代码的健壮性