# Calculator using RPN

Page 1 of 1

## 8 Replies - 9211 Views - Last Post: 07 December 2008 - 04:01 AMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=75110&amp;s=dbd55f435176f1d2457e67e50b171878&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 projeckt

• New D.I.C Head

Reputation: 0
• Posts: 10
• Joined: 15-November 08

# Calculator using RPN

Posted 04 December 2008 - 11:31 PM

Creating a calculator class that allows programs that use it to evaluate strings representing expressions in infix notation. Getting a no such element error right now. Anyone can point me in the right direction or if you see any additional errors please tell me.

```public class Calculator {

public static void main (String[] args) {
Calculator c = new Calculator();
double x = c.evaluate("5.5 + 3.4 + 2.0");
System.out.println("x = " +x+ ";");
}

public Calculator() { }

private static int precedence(String theOp) {
if (theOp.equals("("))
return 0;
else if (theOp.equals("+") || theOp.equals("-"))
return 1;
else if (theOp.equals("*") || theOp.equals("/"))
return 2;
return -1;
}

private static void processOp (String theOp, Stack<String> opStack, Queue<String> result) {
while ((! opStack.isEmpty()) && (precedence(theOp) <= precedence(opStack.first()))) {
result.enqueue(opStack.pop());
}
opStack.push(theOp);
}

private static Queue<String> infixToPostfix(String infixStr) {
Queue<String> result = new Queue<String>();
Stack<String> opStack = new Stack<String>();
int i = 0;
while (i < infixStr.length()) {
if (Character.isDigit(infixStr.charAt(i))) { // process constants
String num_str = "";
while (i < infixStr.length() && Character.isDigit(infixStr.charAt(i))) {
num_str += infixStr.charAt(i++);
}
result.enqueue(num_str);
} else {
switch(infixStr.charAt(i++)) {
case '(': opStack.push("(");
break;
case ')':
while (opStack.first() != "(") {
result.enqueue(opStack.pop());
}
opStack.pop();
break;
case '+': processOp("+", opStack, result);
break;
case '-': processOp("-", opStack, result);
break;
case '*': processOp("*", opStack, result);
break;
case '/': processOp("/", opStack, result);
break;
}
}
}
while (! opStack.isEmpty()) {
result.enqueue(opStack.pop());
}
return result;
}

private double evaluate(String expr) {
Stack<String> exprStack = new Stack<String>();
while(! expr.isEmpty()) {
String x = exprStack.pop();
if (Character.isDigit(expr.charAt(0))) {
exprStack.push(x);
}
else {
int op2 = Integer.parseInt(exprStack.pop());
int op1 = Integer.parseInt(exprStack.pop());
int result = 0;
switch(expr.charAt(0))
{
case '*': result = op1 * op2;
break;
case '+': result = op1 + op2;
break;
case '-': result = op1 - op2;
break;
case '/': result = op1 / op2;
break;
case '%': result = op1 % op2;
break;
}
exprStack.push(x);
}
}
return Double.parseDouble(exprStack.pop());

}

}
```

This post has been edited by projeckt: 04 December 2008 - 11:33 PM

Is This A Good Question/Topic? 0

## Replies To: Calculator using RPN

### #2 Unknown Hero

Reputation: 17
• Posts: 51
• Joined: 04-September 07

## Re: Calculator using RPN

Posted 05 December 2008 - 12:56 AM

I see one error here:
```Stack<String> exprStack = new Stack<String>();
while(! expr.isEmpty()) {
String x = exprStack.pop();

```

You are trying to get element from an empty Stack.

### #3 projeckt

• New D.I.C Head

Reputation: 0
• Posts: 10
• Joined: 15-November 08

## Re: Calculator using RPN

Posted 05 December 2008 - 03:40 AM

Hm. You are right. I want to pass the expression to it after the using the postfix, but it's of Queue type. Any suggestions?

### #4 Unknown Hero

Reputation: 17
• Posts: 51
• Joined: 04-September 07

## Re: Calculator using RPN

Posted 05 December 2008 - 10:58 AM

Can you be more specific with what you have to do please?

Is this the program you have to do:
INPUT:
5 6 +
OUTPUT:
11

### #5 projeckt

• New D.I.C Head

Reputation: 0
• Posts: 10
• Joined: 15-November 08

## Re: Calculator using RPN

Posted 05 December 2008 - 12:40 PM

Essentially, but the input that the user would give would be a normal arithmetic expression. The input would be
"5 + 6" which would be passed to the evaluate method. This expression would first be converted into RPN notation 5 6 +, then evaluated to 11.

### #6 projeckt

• New D.I.C Head

Reputation: 0
• Posts: 10
• Joined: 15-November 08

## Re: Calculator using RPN

Posted 05 December 2008 - 06:57 PM

projeckt, on 5 Dec, 2008 - 11:40 AM, said:

Essentially, but the input that the user would give would be a normal arithmetic expression. The input would be
"5 + 6" which would be passed to the evaluate method. This expression would first be converted into RPN notation 5 6 +, then evaluated to 11.

exprStack.push(Queue.remove(infixToPostfix(expr)));

I believe that would help my problem. However, I am not too sure how to implement a class that uses the Queue interface to allow me to use the remove method.

### #7 projeckt

• New D.I.C Head

Reputation: 0
• Posts: 10
• Joined: 15-November 08

## Re: Calculator using RPN

Posted 05 December 2008 - 08:04 PM

```public class Calculator {

public static void main (String[] args) {
Calculator c = new Calculator();
double x = c.evaluate("5.5 + 3.4 + 2.0");
System.out.println("x = " +x+ ";");
}

public Calculator() { }

private static int precedence(String theOp) {
if (theOp.equals("("))
return 0;
else if (theOp.equals("+") || theOp.equals("-"))
return 1;
else if (theOp.equals("*") || theOp.equals("/"))
return 2;
return -1;
}

private static void processOp (String theOp, Stack<String> opStack, Queue<String> result) {
while ((! opStack.isEmpty()) && (precedence(theOp) <= precedence(opStack.first()))) {
result.enqueue(opStack.pop());
}
opStack.push(theOp);
}

private static Queue<String> infixToPostfix(String infixStr) {
Queue<String> result = new Queue<String>();
Stack<String> opStack = new Stack<String>();
int i = 0;
while (i < infixStr.length()) {
if (Character.isDigit(infixStr.charAt(i))) { // process constants
String num_str = "";
while (i < infixStr.length() && Character.isDigit(infixStr.charAt(i))) {
num_str += infixStr.charAt(i++);
}
result.enqueue(num_str);
} else {
switch(infixStr.charAt(i++)) {
case '(': opStack.push("(");
break;
case ')':
while (opStack.first() != "(") {
result.enqueue(opStack.pop());
}
opStack.pop();
break;
case '+': processOp("+", opStack, result);
break;
case '-': processOp("-", opStack, result);
break;
case '*': processOp("*", opStack, result);
break;
case '/': processOp("/", opStack, result);
break;
}
}
}
while (! opStack.isEmpty()) {
result.enqueue(opStack.pop());
}
return result;
}

private double evaluate(String expr) {
Queue<String> r = infixToPostfix(expr);
Stack<String> exprStack = new Stack<String>();
exprStack.push(r.dequeue());
while(! expr.isEmpty()) {
String x = exprStack.pop();
if (Character.isDigit(expr.charAt(0))) {
exprStack.push(x);
}
else {
int op2 = Integer.parseInt(exprStack.pop());
int op1 = Integer.parseInt(exprStack.pop());
int result = 0;
switch(expr.charAt(0))
{
case '*': result = op1 * op2;
break;
case '+': result = op1 + op2;
break;
case '-': result = op1 - op2;
break;
case '/': result = op1 / op2;
break;
case '%': result = op1 % op2;
break;
}
exprStack.push(x);
}
}
return Double.parseDouble(exprStack.pop());

}

}
```

Changed it so that the postfixed expression is passed to the empty stack. Now it's running in an infinite loop. Any suggestions?

### #8 pbl

• There is nothing you can't do with a JTable

Reputation: 8378
• Posts: 31,956
• Joined: 06-March 08

## Re: Calculator using RPN

Posted 05 December 2008 - 10:33 PM

I don't see why you take care of parenthesis () RPN calculator do not need them... and actually none of them has parenthesis on their "keyboard"

### #9 projeckt

• New D.I.C Head

Reputation: 0
• Posts: 10
• Joined: 15-November 08

## Re: Calculator using RPN

Posted 07 December 2008 - 04:01 AM

I got to the program to work on some base cases. The only problem I have now is it won't process decimals. It just ignores them all together. For example, if you look in the main, the y string would be processed as 0 5 2 0 3 1 6 2 / + * 2 25 -. Any suggestions for actually processing decimal numbers?

```import java.util.*;

public class Calculator  {
public static void main (String[] args) {
Calculator c = new Calculator();
double x = c.evaluate("0 / 5");
double y = c.evaluate("0.5 * (2.0 + 3.1/6.2) - 2.25");
System.out.println("x = " +x+"; y = "+y);
}

public Calculator() {
}

private static int precedence(String theOp) {
if (theOp.equals("("))
return 0;
else if (theOp.equals("+") || theOp.equals("-"))
return 1;
else if (theOp.equals("*") || theOp.equals("/"))
return 2;
return -1;
}

private static void processOp (String theOp, Stack<String> opStack, Queue<String> result) {
while ((! opStack.isEmpty()) && (precedence(theOp) <= precedence(opStack.first()))) {
result.enqueue(opStack.pop());
}
opStack.push(theOp);
}

private static Queue<String> infixToPostfix(String infixStr) {
Queue<String> result = new Queue<String>();
Stack<String> opStack = new Stack<String>();
int i = 0;
while (i < infixStr.length()) {
if (Character.isDigit(infixStr.charAt(i))) { // process constants
String num_str = "";
while (i < infixStr.length() && Character.isDigit(infixStr.charAt(i))) {
num_str += infixStr.charAt(i++);
}
result.enqueue(num_str);
} else {
switch(infixStr.charAt(i++)) {
case '(': opStack.push("(");
break;
case ')':
while (opStack.first() != "(") {
result.enqueue(opStack.pop());
}
opStack.pop();
break;
case '+': processOp("+", opStack, result);
break;
case '-': processOp("-", opStack, result);
break;
case '*': processOp("*", opStack, result);
break;
case '/': processOp("/", opStack, result);
break;
}
}
}
while (! opStack.isEmpty()) {
result.enqueue(opStack.pop());
}
return result;
}

private double evaluate(String expr) {
Queue<String> r = infixToPostfix(expr);
Stack<String> exprStack = new Stack<String>();
double value;
String temp = "";
while (! r.isEmpty()) {
temp = temp + " "+ r.dequeue();
}
System.out.println(temp);
StringTokenizer postfix = new StringTokenizer(temp);
String x;
while (postfix.hasMoreTokens()) {
x = postfix.nextToken();
if (Character.isDigit(x.charAt(0))) {
exprStack.push(x);
} else {
double op2 = Double.parseDouble(exprStack.pop());
double op1 = Double.parseDouble(exprStack.pop());
double result = 0;
switch(x.charAt(0)) {
case '*': result = op1 * op2;
break;
case '+': result = op1 + op2;
break;
case '-': result = op1 - op2;
break;
case '/':
//   if op1 || op2 == 0) {
//   throw new IllegalArgumentException("Operands cannot be zero while dividing.");
//			} else {
result = op1 / op2;
//		  }
break;
case '%': result = op1 % op2;
break;
}
String y = Double.toString(result);
exprStack.push(y);
}
}
value = Double.parseDouble(exprStack.pop());
return value;
}
}
```

This post has been edited by projeckt: 07 December 2008 - 04:03 AM

Page 1 of 1

 .related ul { list-style-type: circle; font-size: 12px; font-weight: bold; } .related li { margin-bottom: 5px; background-position: left 7px !important; margin-left: -35px; } .related h2 { font-size: 18px; font-weight: bold; } .related a { color: blue; }