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();
}
}