Calculadora RPN

Uma expressão aritmética está em notação postfix (também chamada reverse polish notation ou RPN)se cada operador for colocado depois dos seus operandos. Por exemplo 3*(4+5) fica 3 4 5 + *. A notação 3*(4+5) chama-se infix. As expressões quando estão em notação postfix, são mais fáceis de serem processadas pelos computadores do que as expressões infix.
A seguinte classe processa expressões rpn e efectua as respectivas operações aritméticas. O centro nevrálgico do programa é o interface Deque e a classe ArrayDeque. Um deque é uma queue com duas saídas, ou seja, é uma estrutura linear que permite inserções e remoções só nos dois extremos (Deque).
Então, temos:

/**
 * Esta classe faz o parsing de expressões em postfix
 * (reverse polish notation)
 * e efectua as respectivas operações aritméticas
 *
 * @author Manuel
 *
 */
public class RPNCalculator {

	private static Deque stack =
		new ArrayDeque();
	/**
	 *
	 * @param input
	 */
	public static void calculate(String input) {
		char ch = input.charAt(0);
		if (ch == '+' || ch == '-' || ch == '*'
			|| ch == '/') {
			double y =
			  Double.parseDouble(
                                          stack.pop());
			double x =
			  Double.parseDouble(
			    stack.pop());
			double z = 0.0;
			switch (ch) {
			case '+':
				z = x + y;
				break;
			case '-':
				z = x - y;
				break;
			case '*':
				z = x * y;
				break;
			case '/':
				z = x / y;
				break;
			}
			System.out.printf
			  ("\t%.2f %c %.2f = %.2f%n",
			    x, ch, y, z);
			stack.push(new Double(z).toString());
		} else {
			stack.push(input);
		}
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while (true) {
			String input = in.nextLine();
			calculate(input);
			if(input.equalsIgnoreCase("q"))
				break;
		}
	}
}

A parte chata é que para fazer uma qualquer operação, temo primeiro que converter a expresão para a sua correspondente versão RPN. Segue um programa que faz isso mesmo:

public class ConvertInfixToPostfix {

	public static void main(String[] args){

		Deque stack =
			new ArrayDeque();
		String line =
			new Scanner(System.in).nextLine();
		System.out.println(line);
		Scanner scanner = new Scanner(line);
		while(scanner.hasNext()){
			if(scanner.hasNextInt()){
				System.out.print(
				  scanner.nextInt() + " ");
			}else{
				String str = scanner.next();
				if("+-*/".indexOf(str) >= 0){
					stack.push(str);
				}else if(str.equals(")")){
				  System.out.print(
				    stack.pop() + " ");
				}
			}
		}
		while(!stack.isEmpty()){
			System.out.print(stack.pop() + " ");
		}
		System.out.println();
	}
}

Deixar uma Resposta