计算器未正确执行BODMAS

时间:2018-04-04 15:20:33

标签: java math

我有一项任务,我需要编写一份遵循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。谁能弄清楚这里出了什么问题?

感谢。

2 个答案:

答案 0 :(得分:0)

问题是你的表达式包含更多'+'和' - ' 在这种情况下,应该从左到右评估操作数。

你可以试试这个:

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();
  }
}

答案 1 :(得分:0)

我或多或少地重写了你的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