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


    作业要求地址: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、算术符优先级表

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

    3.2、计算式子答案方法

     1 private static Float getResult(Stack<Float> operatedNumber, Stack<Character> operatedSign) {
     2     int count = 0, flag=1;
     3     Stack<Float> tempNumber = new Stack<Float>();
     4     Stack<Character> tempSign = new Stack<Character>();
     5     Float newData = null, numberTop = null, numberNext = null, numberNextNext = null;
     6     Character signTop = null, signNext = null;
     7     while (operatedNumber.size() > 1 && operatedSign.get(operatedSign.size() - 1) != '=') {
     8         switch (signPriority[getPosition(operatedSign.get(operatedSign.size() - 1))][getPosition(operatedSign.get(operatedSign.size() - 2))]) {
     9             case '>':
    10                 numberTop = operatedNumber.pop();
    11                 numberNext = operatedNumber.pop();
    12                 signTop = operatedSign.pop();
    13                 newData = calculate(numberTop, signTop, numberNext);
    14                 operatedNumber.push(newData);
    15                 break;
    16             case '<':
    17                 numberTop = operatedNumber.pop();
    18                 numberNext = operatedNumber.pop();
    19                 numberNextNext = operatedNumber.pop();
    20                 signTop = operatedSign.pop();
    21                 signNext = operatedSign.pop();
    22                 if (!operatedSign.isEmpty()&& (signNext == '(' || operatedSign.get(operatedSign.size()-1)=='(')) {
    23                     if (operatedSign.get(operatedSign.size()-1)=='(') {
    24                         operatedSign.pop();
    25                         operatedNumber.push(numberNextNext);
    26                         flag=0;
    27                     }
    28                     else {
    29                         operatedNumber.add(numberNextNext);
    30                         operatedNumber.add(numberNext);
    31                     }
    32                     while(operatedSign.get(operatedSign.size()-1)!=')') {
    33                         tempSign.add(operatedSign.pop());
    34                         count++;
    35                     }
    36                     tempSign.push('=');
    37                     for (int i =0; i<count+1; i++) {
    38                         tempNumber.add(operatedNumber.pop());
    39                     }
    40                     tempNumber = setNumberReserve(tempNumber);
    41                     tempSign = setSignReserve(tempSign);
    42                     if (flag==1) {
    43                         newData = calculate(numberTop, signTop, getResult(tempNumber,tempSign));
    44                         operatedNumber.push(newData);
    45                     }
    46                     else {
    47                         newData = calculate(numberNext, signNext, getResult(tempNumber,tempSign));
    48                         operatedNumber.push(newData);
    49                         operatedNumber.push(numberTop);
    50                         operatedSign.push(signTop);
    51                     }
    52                 }
    53                 else {
    54                     newData = calculate(numberNext, signNext, numberNextNext);
    55                     operatedSign.push(signTop);
    56                     operatedNumber.push(newData);
    57                     operatedNumber.push(numberTop);
    58                 }
    59                 break;
    60             case '=':
    61                 operatedSign.pop();
    62                 operatedSign.pop();
    63                 break;
    64             default:
    65                 break;
    66         }
    67     }
    68     return operatedNumber.get(0);
    69 }

      3.2 处理用户输入答案方法

     1 private static Float inputAnswer() {
     2         String answer = null;
     3         String pattern = "(\d+)/(\d+)";
     4         Scanner in = new Scanner(System.in);
     5         boolean isVaild = false;
     6         while (!isVaild) {
     7             try {
     8                 answer = in.nextLine();
     9                 isVaild = true;
    10                 Pattern p = Pattern.compile(pattern);
    11                 Matcher matcher = p.matcher(answer);
    12                 if (matcher.find()) {
    13                     return Float.parseFloat(matcher.group(1)) / Float.parseFloat(matcher.group(2));
    14                 }
    15                 else {
    16                     return Float.parseFloat(answer);
    17                 }
    18             }
    19             catch (Exception e) {
    20                 System.out.println("输入错误!请重新输入");
    21                 in.nextLine();
    22             }
    23         }
    24         return Float.parseFloat("0");
    25     }

    4.运行效果

    5.遇到的问题

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

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

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

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

    3.生成分数的控制

    生成分数途中可能出现假分数,所以先记录下分母的值,控制分子在生成时比分母小的范围内随机生成。生成分数约分问题,因为想不到好的方法,有待解决。

     

     

  • 相关阅读:
    swagger Unable to render this definition
    企业应用向ASP.NET Core迁移
    .NET Core EF框架使用SQL server 2008数据库分页问题:Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement
    .NET Core应用中使用分布式缓存及内存缓存
    .NET Core Session的使用方法
    .NET Core 2.1中的HttpClientFactory最佳实践
    转载:ZooKeeper Programmer's Guide(中文翻译)
    Python【map、reduce、filter】内置函数使用说明(转载)
    Python使用基础
    Redis Sentinel:集群Failover解决方案(转载)
  • 原文地址:https://www.cnblogs.com/-QAQ/p/9765576.html
Copyright © 2020-2023  润新知