【问题标题】:Calculator not doing BODMAS correctly计算器未正确执行 BODMAS
【发布时间】:2018-04-04 15:20:33
【问题描述】:

我有一个任务,我需要编写一个遵循 BODMAS 法则的计算器。我已经为计算器编写了代码,但它没有正确通过 BODMAS 规则。这是我的代码: 公共类计算器{

import java.util.ArrayList;
import java.util.regex.Pattern;

public class Calculator {

    String expression;
    public Calculator(String expr) {
        this.expression = expr.replaceAll("\\s+", "");
    }

    public double evalExpr() {
        return eval(expression);
    }

    private double eval(String input) {
        if (input.contains("-")) {
            String[] operands = input.split("\\-", 2);
            return eval(operands[0]) - eval(operands[1]);
        } else if (input.contains("+")) {
            String[] operands = input.split("\\+", 2);
            return eval(operands[0]) + eval(operands[1]);
        } else if (input.contains("*")) {
            String[] operands = input.split("\\*", 2);
            return eval(operands[0]) * eval(operands[1]);
        } else if (input.contains("/")){
            String[] operands = input.split("\\/", 2);
            return eval(operands[0]) / eval(operands[1]);
        } else if (input.matches("[0-9]*")) {
            return Integer.parseInt(input);
        } else {
            throw new RuntimeException();
        }
    }

}




public class Main {
    public static void main(String[] args) {
        String input = "6*8/7+6-9+5/4*3-8+6";
        Calculator calc = new Calculator(input);
        double answer = calc.evalExpr();
        System.out.println(answer);
    }
}

但是这个版本由于某种原因没有通过 BODMAS。计算器应返回 ~ 5.61 作为答案,但返回 14.10。我不明白为什么我认为 Java 会自动为你做 BODMAS。谁能弄清楚这里出了什么问题?

谢谢。

【问题讨论】:

  • 所以你希望java知道你碰巧想用字符串做一个计算器?可悲的是它无法读懂你的想法
  • @dave 你能提供任何实际的帮助还是只提供一些无聊的、不必要的 cmets?
  • 看起来如果你在 eval 中重新排序 if-else-if,你会得到不同的结果,尽管我还不确定排序应该是什么。 @dave 你读过代码吗?它编译并运行。
  • 我知道它编译他们在说为什么 java 没有得到正确的答案,而不是为什么它不起作用,我只是说原因是他们创建的不是 java
  • 你不能用这么简单的代码制作一个兼容 BODMAS 的计算器。您将需要某种完整的解析器,例如LALR。

标签: java math


【解决方案1】:

问题是您的表达式包含更多的“+”和“-”。
在这种情况下,操作数应该从左到右进行计算。

你可以试试这个:

private double eval(String input) {
  if (input.contains("-") || input.contains("+"))
  {
    // Get all operands
    String[] operands;
    operands = input.split("[\\+\\-]");

    // Evaluate them from left to right
    int    counter;
    int    index_operator;
    char   operator;
    String operand;
    double result;
    operand = operands[0];
    result = eval(operand);
    index_operator = operand.length();
    for (counter = 1; counter < operands.length; counter++)
    {
      operator = input.charAt(index_operator);
      operand = operands[counter];
      if (operator == '+')
        result += eval(operand);
      else
        result -= eval(operand);
      index_operator += operand.length() + 1;
    }
    return (result);
  } else if (input.contains("*")) {
      String[] operands = input.split("\\*", 2);
      return eval(operands[0]) * eval(operands[1]);
  } else if (input.contains("/")){
      String[] operands = input.split("\\/", 2);
      return eval(operands[0]) / eval(operands[1]);
  } else if (input.matches("[0-9]*")) {
      return Integer.parseInt(input);
  } else {
      throw new RuntimeException();
  }
}

【讨论】:

    【解决方案2】:

    我或多或少地重写了您的Calculator,以使其从左到右评估所有加法和减法。
    可能会有所帮助。

    import java.util.*;
    
    public class Calculator
    {
      String expression;
    
      public Calculator(String expr)
      {
        expression = expr.replaceAll("\\s+", "");
      }
    
      class Operation
      {
        public char   operator;
        public String operand;
      }
    
      public double evalExpr()
      {
        // -----------------
        // Initialize result
        // -----------------
        double result;
        result = 0;
    
        // -------------------------------
        // Split expression into its parts
        // -------------------------------
        List<Operation> operations;
        operations = splitExpression(expression);
    
        // -------------------
        // Evaluate operations
        // -------------------
        Iterator<Operation> it;
        Operation           operation;
        it = operations.iterator();
        while (it.hasNext())
        {
          operation = it.next();
          switch (operation.operator)
          {
            case '+':
              result += eval(operation.operand);
              break;
            case '-':
              result -= eval(operation.operand);
              break;
            default: // This is the first element in the list
              result = eval(operation.operand);
              break;
          }
        }
    
        // ----
        // Done
        // ----
        return (result);
    
      } // evalExpr
    
      /**
       * This method splits the specified expression.
       * The result is a list of operators and operands.
       * <br>The first element will have an empty operator.
       **/
      private List<Operation> splitExpression(String expression)
      {
        // -----------------
        // Initialize result
        // -----------------
        List<Operation> result;
        result = new ArrayList<Operation>();
    
        // -------------------------------
        // Split expression into its parts
        // -------------------------------
        String[] parts;
        parts = expression.split("[\\+\\-]");
    
        // ----------------------------
        // Convert into internal format
        // ----------------------------
        int           counter;
        int           index_operator;
        Operation part;
        index_operator = 0;
        for (counter = 0; counter < parts.length; counter++)
        {
          // ----------------------------
          // Extract operand and operator
          // ----------------------------
          part = new Operation();
          part.operand = parts[counter];
          if (counter == 0)
            part.operator = '\0';
          else
          {
            part.operator = expression.charAt(index_operator);
            index_operator++;
          }
    
          // ------------------
          // We got another one
          // ------------------
          result.add(part);
    
          // ----------------------
          // Point to next operator
          // ----------------------
          index_operator += part.operand.length();
    
        } // for all parts
    
        // ----
        // Done
        // ----
        return (result);
    
      } // splitExpression
    
      private double eval(String input)
      {
        if (input.contains("*"))
        {
          String[] operands = input.split("\\*", 2);
          return eval(operands[0]) * eval(operands[1]);
        }
        else if (input.contains("/"))
        {
          String[] operands = input.split("\\/", 2);
          return eval(operands[0]) / eval(operands[1]);
        }
        else if (input.matches("[0-9]*"))
          return Integer.parseInt(input);
        else
          throw new RuntimeException();
      }
    
      public static void main(String[] args)
      {
        String input = "6*8/7+6-9+5/4*3-8+6";
        Calculator calc = new Calculator(input);
        System.out.println(input);
        double answer = calc.evalExpr();
        System.out.println(answer);
      }
    
    } // class Calculator
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      相关资源
      最近更新 更多