import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;
public class Postfix {
private Map<Character, Integer> operatory = new HashMap<Character, Integer>();
public Postfix() {
operatory.put('+', -2);
operatory.put('-', -2);
operatory.put('*', -3);
operatory.put('/', -3);
operatory.put('^', 4);
}
private boolean jeOperator(char op) {
return operatory.containsKey(op);
}
private int porovnajPrioritu(char op1, char op2) {
int pr1 = Math.abs(operatory.get(op1));
int pr2 = Math.abs(operatory.get(op2));
return pr1 - pr2;
}
private boolean jeLavoAsociativny(char op) {
return operatory.get(op) < 0;
}
private double vyhodnot(double arg1, double arg2, char op) {
switch (op) {
case '+':
return arg1 + arg2;
case '-':
return arg1 - arg2;
case '*':
return arg1 * arg2;
case '/':
return arg1 / arg2;
case '^':
return Math.pow(arg1, arg2);
default:
throw new RuntimeException("Nepoznam operator!");
}
}
private String infixNaPostfix(String vyraz) {
StringBuilder sb = new StringBuilder();
Stack<Character> opStack = new Stack<Character>();
Scanner s = new Scanner(vyraz);
s.useLocale(Locale.US);
while (s.hasNext()) {
String t = s.next();
char op = t.charAt(0);
if (jeOperator(op)) {
if (!opStack.isEmpty() && jeOperator(opStack.peek())) {
boolean podmienkaL = jeLavoAsociativny(op)
&& porovnajPrioritu(op, opStack.peek()) <= 0;
boolean podmienkaR = !jeLavoAsociativny(op)
&& porovnajPrioritu(op, opStack.peek()) < 0;
if (podmienkaL || podmienkaR) {
sb.append(opStack.pop() + " ");
}
}
opStack.push(op);
} else if (op == '(') {
opStack.push(op);
} else if (op == ')') {
while (!opStack.isEmpty() && opStack.peek() != '(')
sb.append(opStack.pop() + " ");
opStack.pop(); // vyhodit '('
} else {
sb.append(t + " ");
}
}
while (!opStack.isEmpty())
sb.append(opStack.pop() + " ");
return sb.toString();
}
public double vyhodnotInfix(String vyraz) {
String postfix = infixNaPostfix(vyraz);
return vyhodnotPostfix(postfix);
}
public double vyhodnotPostfix(String vyraz) {
Scanner s = new Scanner(vyraz);
s.useLocale(Locale.US);
Stack<Double> zasobnik = new Stack<Double>();
while (s.hasNext()) {
String cast = s.next();
if (jeOperator(cast.charAt(0))) {
double arg2 = zasobnik.pop();
double arg1 = zasobnik.pop();
zasobnik.push(vyhodnot(arg1, arg2, cast.charAt(0)));
} else {
zasobnik.push(Double.parseDouble(cast));
}
}
return zasobnik.pop();
}
public static void main(String[] args) {
String vyraz = "( 1 + 5 ) * 8 - 7 * ( 5 + 2 )";
Postfix p = new Postfix();
System.out.println(p.vyhodnotInfix(vyraz));
}
}