Untitled

mail@pastecode.io avatar
unknown
plain_text
22 days ago
5.4 kB
3
Indexable
Never
package com.example.calculator;
import java.util.*;

public class Calculator {

    private static final Map<String, Integer> precedence = new HashMap<>();
    private static final Map<String, Double> constants = new HashMap<>();

    static {
        precedence.put("+", 1);
        precedence.put("-", 1);
        precedence.put("*", 2);
        precedence.put("/", 2);
        precedence.put("%", 2);
        precedence.put("(", 0);
        precedence.put(")", 0);

        constants.put("pi", Math.PI);
        constants.put("e", Math.E);
    }

    public static double evaluateExpression(String expression) {
        List<String> tokens = tokenize(expression);
        Queue<String> postfix = toPostfix(tokens);
        return evaluatePostfix(postfix);
    }

    private static List<String> tokenize(String expression) {
        List<String> tokens = new ArrayList<>();
        StringBuilder number = new StringBuilder();
        StringBuilder function = new StringBuilder();

        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);

            if (Character.isDigit(c) || c == '.') {
                number.append(c);
            } else {
                if (number.length() > 0) {
                    tokens.add(number.toString());
                    number.setLength(0);
                }
                if (Character.isLetter(c)) {
                    function.append(c);
                } else {
                    if (function.length() > 0) {
                        tokens.add(function.toString());
                        function.setLength(0);
                    }
                    if (c != ' ') {
                        tokens.add(String.valueOf(c));
                    }
                }
            }
        }

        if (number.length() > 0) {
            tokens.add(number.toString());
        }
        if (function.length() > 0) {
            tokens.add(function.toString());
        }

        return tokens;
    }

    private static Queue<String> toPostfix(List<String> tokens) {
        Queue<String> output = new LinkedList<>();
        Stack<String> operators = new Stack<>();

        for (String token : tokens) {
            if (isNumber(token) || isConstant(token)) {
                output.add(token);
            } else if (isFunction(token)) {
                operators.push(token);
            } else if (token.equals("(")) {
                operators.push(token);
            } else if (token.equals(")")) {
                while (!operators.isEmpty() && !operators.peek().equals("(")) {
                    output.add(operators.pop());
                }
                operators.pop();  // Remove '('
                if (!operators.isEmpty() && isFunction(operators.peek())) {
                    output.add(operators.pop());
                }
            } else { // Operator
                while (!operators.isEmpty() && precedence.get(token) <= precedence.get(operators.peek())) {
                    output.add(operators.pop());
                }
                operators.push(token);
            }
        }

        while (!operators.isEmpty()) {
            output.add(operators.pop());
        }

        return output;
    }

    private static double evaluatePostfix(Queue<String> postfix) {
        Stack<Double> stack = new Stack<>();

        while (!postfix.isEmpty()) {
            String token = postfix.poll();
            if (isNumber(token)) {
                stack.push(Double.parseDouble(token));
            } else if (isConstant(token)) {
                stack.push(constants.get(token));
            } else if (isFunction(token)) {
                double a = stack.pop();
                stack.push(evaluateFunction(token, a));
            } else { // Operator
                double b = stack.pop();
                double a = stack.pop();
                stack.push(evaluateOperator(token, a, b));
            }
        }

        return stack.pop();
    }

    private static double evaluateFunction(String function, double a) {
        switch (function) {
            case "sin": return Math.sin(a);
            case "cos": return Math.cos(a);
            case "tan": return Math.tan(a);
            case "ln": return Math.log(a);
            case "lg": return Math.log10(a);
            default: throw new IllegalArgumentException("Unknown function: " + function);
        }
    }

    private static double evaluateOperator(String operator, double a, double b) {
        switch (operator) {
            case "+": return a + b;
            case "-": return a - b;
            case "*": return a * b;
            case "/": return a / b;
            case "%": return a % b;
            default: throw new IllegalArgumentException("Unknown operator: " + operator);
        }
    }

    private static boolean isNumber(String token) {
        try {
            Double.parseDouble(token);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private static boolean isConstant(String token) {
        return constants.containsKey(token);
    }

    private static boolean isFunction(String token) {
        return precedence.containsKey(token) && precedence.get(token) > 2;
    }
}
Leave a Comment