Untitled
unknown
plain_text
a year ago
6.3 kB
9
Indexable
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("^", 3);
precedence.put("(", 0);
precedence.put(")", 0);
constants.put("\u03C0", Math.PI);
constants.put("e", Math.E);
}
public static double evaluateExpression(String expression) {
List<String> tokens = tokenize(expression.trim());
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();
boolean expectNegativeNumber = true;
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (Character.isDigit(c) || c == '.') {
number.append(c);
expectNegativeNumber = false;
} else {
if (number.length() > 0) {
tokens.add(number.toString());
number.setLength(0);
}
if (Character.isLetter(c)) {
function.append(c);
expectNegativeNumber = false;
} else {
if (function.length() > 0) {
tokens.add(function.toString());
function.setLength(0);
}
if(c == '-' && expectNegativeNumber) {
number.append(c);
}
else {
if (c != ' ') {
tokens.add(String.valueOf(c));
}
expectNegativeNumber = (c == '(' || precedence.containsKey(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 "/": {
if(b == 0) throw new ArithmeticException("Not division by zero: " + b);
else return a / b;
}
case "%": return a % b;
case "^": return Math.pow(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 token.equals("sin") || token.equals("cos") || token.equals("tan") || token.equals("ln") ||token.equals("lg");
}
}Editor is loading...
Leave a Comment