Java计算器认为不对

问题描述 投票:0回答:1

我的计算器在计算 2 * (3 + 4) / 5 - 1 时得到 3.5,尽管正确的选项是 1.8 你能告诉我哪里出了问题吗?

evaluateExpression 方法以输入表达式作为参数进行调用。此方法执行表达式的计算并将结果作为双精度值返回。

在evaluateExpression 方法中,首先使用带有正则表达式(\s+) 的replaceAll 方法处理输入表达式以删除所有空白字符。这可以确保表达式中没有任何不必要的空格。

创建两个堆栈:数字用于存储表达式中遇到的数值,运算符用于存储遇到的运算符。

该方法使用 for 循环迭代表达式中的每个字符。

如果字符是数字,则表示数值。该程序通过迭代后续字符直到遇到非数字字符或小数点 (.) 来提取整个数字。然后,提取的数字被解析为双精度值并推送到数字堆栈上。

如果字符是左括号 (,则将其推入运算符堆栈。

如果该字符是右括号),则表示子表达式的结束。程序从运算符栈中弹出运算符并执行相应的计算,直到遇到左括号。如果运算符是三角函数(c、s 或 t),则会将该函数应用于数字堆栈的顶部值。否则,它会从数字堆栈中弹出两个值,对它们应用运算符,然后将结果推回到数字堆栈中。

如果字符是运算符(+、-、*、/、^、c、s 或 t),程序将检查当前运算符与运算符堆栈顶部运算符的优先级。如果当前运算符具有更高的优先级,则将其推送到运算符堆栈中。如果当前运算符的优先级较低或相同,则程序从运算符堆栈中弹出运算符并执行计算,直到遇到优先级较低的运算符或运算符堆栈变空。遵循与步骤 8 中所述应用运算符和三角函数相同的逻辑。

如果该字符既不是数字,也不是括号,也不是运算符,则表示无效字符,并抛出 IllegalArgumentException 并附带相应的错误消息。

处理完表达式中的所有字符后,程序检查运算符堆栈上是否还有剩余的运算符。它弹出运算符并执行步骤 8 中所述的计算,直到运算符堆栈变空。

最后,程序检查数字堆栈上是否只剩下一个值。如果不是,则表明表达式中存在错误,并抛出 IllegalArgumentException 和相应的错误消息。

数字堆栈上剩余的单个值是表达式的计算结果,由evaluateExpression方法返回。

在main方法中,获取用户输入,并调用evaluateExpression方法对表达式求值。然后将结果打印到控制台。如果评估过程中出现任何异常,则会打印相应的错误消息。

总体而言,该程序使用堆栈来处理运算符和数字,并遵循运算符优先级规则来正确计算数学表达式。它支持基本算术运算符(+、-、*、/、^)和三角函数(cos、sin、tan)。

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("input: ");
        String input = scanner.nextLine();

        try {
            double result = evaluateExpression(input);
            System.out.println(result);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public static double evaluateExpression(String expression) {
        expression = expression.replaceAll("\\s+", "");
        Stack<Double> numbers = new Stack<>();
        Stack<Character> operators = new Stack<>();

        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (Character.isDigit(c)) {
                StringBuilder numStr = new StringBuilder();
                while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
                    numStr.append(expression.charAt(i));
                    i++;
                }
                i--;
                numbers.push(Double.parseDouble(numStr.toString()));
            } else if (c == '(') {
                operators.push(c);
            } else if (c == ')') {
                while (operators.peek() != '(') {
                    char operator = operators.pop();
                    if (operator == 'c' || operator == 's' || operator == 't') {
                        numbers.push(applyTrigOperator(operator, numbers.pop()));
                    } else {
                        double b = numbers.pop();
                        double a = numbers.pop();
                        numbers.push(applyOperator(operator, a, b));
                    }
                }
                operators.pop();
            } else if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == 'c' || c == 's' || c == 't') {
                while (!operators.isEmpty() && hasPrecedence(c, operators.peek())) {
                    char operator = operators.pop();
                    if (operator == 'c' || operator == 's' || operator == 't') {
                        numbers.push(applyTrigOperator(operator, numbers.pop()));
                    } else {
                        double b = numbers.pop();
                        double a = numbers.pop();
                        numbers.push(applyOperator(operator, a, b));
                    }
                }
                operators.push(c);
            } else {
                throw new IllegalArgumentException("erorr" + c);
            }
        }

        while (!operators.isEmpty()) {
            char operator = operators.pop();
            if (operator == 'c' || operator == 's' || operator == 't') {
                numbers.push(applyTrigOperator(operator, numbers.pop()));
            } else {
                double b = numbers.pop();
                double a = numbers.pop();
                numbers.push(applyOperator(operator, a, b));
            }
        }

        if (numbers.size() != 1) {
            throw new IllegalArgumentException("error");
        }

        return numbers.pop();
    }

    private static double applyOperator(char operator, double a, double b) {
        switch (operator) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                if (b == 0) {
                    throw new ArithmeticException("/0");
                }
                return a / b;
            case '^':
                return Math.pow(a, b);
        }
        return 0;
    }

    private static double applyTrigOperator(char operator, double a) {
        switch (operator) {
            case 'c':
                return Math.cos(Math.toRadians(a));
            case 's':
                return Math.sin(Math.toRadians(a));
            case 't':
                return Math.tan(Math.toRadians(a));
        }
        return 0;
    }

    private static boolean hasPrecedence(char op1, char op2) {
        if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) {
            return true;
        }
        if ((op1 == '^') && (op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/')) {
            return true;
        }
        if ((op1 == 'c' || op1 == 's' || op1 == 't') && (op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/')) {
            return true;
        }
        return false;
    }
}
java stack java.util.scanner calculator
1个回答
-2
投票

我认为你的代码是垃圾 你应该删除你的 acc 并且永远不要再编码 你的代码中的问题是如此明显,我什至不想标记它 祝街道清洁工工作顺利

© www.soinside.com 2019 - 2024. All rights reserved.