Calculate negatives in the stack calculator - java

Bear with me, I'm a little fried right now from getting this all together, but I'm at the final stretch. I've made a calculator in java that takes an infix equation and then changes it to postfix. It also takes variables! I'm made it so my postfix includes negative numbers from infix. This would look like so:
infix: 1+-2*(4/2)
postfix: 12_42/*+
So obviously I got it working where negatives are '_' in postfix. Cool yeah? Ok, but now I gotta get my calculator to read them and I'm just getting brain-fart on where it goes on the stack and what I do to make it work without making a condition for all forms of operands. Here is what I have:
import java.util.Stack;
/**
*
* #author rtibbetts268
*/
public class InfixToPostfix
{
/**
* Operators in reverse order of precedence.
*/
private static final String operators = "-+/*_";
private static final String operands = "0123456789x";
/*public int evalInfix(String infix)
{
return evaluatePostfix(convert2Postfix(infix));
}*/
public String xToValue(String postfixExpr, String x)
{
char[] chars = postfixExpr.toCharArray();
StringBuilder newPostfixExpr = new StringBuilder();
for (char c : chars)
{
if (c == 'x')
{
newPostfixExpr.append(x);
}
else
{
newPostfixExpr.append(c);
}
}
return newPostfixExpr.toString();
}
public String convert2Postfix(String infixExpr)
{
char[] chars = infixExpr.toCharArray();
StringBuilder in = new StringBuilder(infixExpr.length());
for (int i = 0; i<chars.length; i++)
{
if (infixExpr.charAt(i) == '-')
{
if (i == 0)
{
in.append('_');
}
else if(isOperand(infixExpr.charAt(i + 1)))
{
if (i != infixExpr.length())
{
if (isOperator(infixExpr.charAt(i-1)))
in.append('_');
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
chars = in.toString().toCharArray();
Stack<Character> stack = new Stack<Character>();
StringBuilder out = new StringBuilder(in.toString().length());
for (char c : chars)
{
if (isOperator(c))
{
while (!stack.isEmpty() && stack.peek() != '(')
{
if (operatorGreaterOrEqual(stack.peek(), c))
{
out.append(stack.pop());
}
else
{
break;
}
}
stack.push(c);
}
else if (c == '(')
{
stack.push(c);
}
else if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
out.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else if (isOperand(c))
{
out.append(c);
}
}
while (!stack.empty())
{
out.append(stack.pop());
}
return out.toString();
}
public int evaluatePostfix(String postfixExpr)//YBEYFCNUNKJKDV IT'S RIGHT HERE!!!
{
char[] chars = postfixExpr.toCharArray();
Stack<Integer> stack = new Stack<Integer>();
for (char c : chars)
{
if (isOperand(c))
{
stack.push(c - '0'); // convert char to int val
}
else if (isOperator(c))
{
int op1 = stack.pop();
int op2 = stack.pop();
int result;
switch (c) {
case '_':
result = op1 * -1;
//stack.push(result);
//break;
case '*':
result = op1 * op2;
stack.push(result);
break;
case '/':
result = op2 / op1;
stack.push(result);
break;
case '+':
result = op1 + op2;
stack.push(result);
break;
case '-':
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}
private int getPrecedence(char operator)
{
int ret = 0;
if (operator == '-' || operator == '+')
{
ret = 1;
}
else if (operator == '*' || operator == '/')
{
ret = 2;
}
if (operator == '_')
{
ret = 3;
}
return ret;
}
private boolean operatorGreaterOrEqual(char op1, char op2)
{
return getPrecedence(op1) >= getPrecedence(op2);
}
private boolean isOperator(char val)
{
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val)
{
return operands.indexOf(val) >= 0;
}
}
I would post less, but it all tends to work cohesively so I'll explain. Look closely at the method called evaluatePostfix() (it's the third one from the top).
This is where the class can take a postfix expression such as the one I named above and calculates it. It calculates an expression with all positive integers, but when I tried to implement it to change a number to negative before it actually ran any of the math, it goes kaputt.
Could anyone assist me with fixing this specific method so it works? I need it to calculate negative integers as well of positive.

Basically the problem is in trying to pop from an empty stack for the '_' case. What you need to do is only attempt to pop op2 from the stack for the '*/+-' cases and not the '_' case.
public int evaluatePostfix(String postfixExpr)
{
char[] chars = postfixExpr.toCharArray();
Stack<Integer> stack = new Stack<Integer>();
for (char c : chars)
{
if (isOperand(c))
{
stack.push(c - '0'); // convert char to int val
}
else if (isOperator(c))
{
int op1 = stack.pop();
int op2;
int result;
switch (c) {
case '_':
result = op1 * -1;
stack.push(result);
break;
case '*':
op2 = stack.pop();
result = op1 * op2;
stack.push(result);
break;
case '/':
op2 = stack.pop();
result = op2 / op1;
stack.push(result);
break;
case '+':
op2 = stack.pop();
result = op1 + op2;
stack.push(result);
break;
case '-':
op2 = stack.pop();
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}

Related

Recursive method to evaluate expressions just work when method is called once

I'm writing a code to valuate math expressions. The code just works when I call the methode once. But I have more than one expression to evaluate and it just break when I call the method more than two times. I get the following error:
-2
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at Evaluate.parse(Evaluate.java:58)
at Evaluate.main(Evaluate.java:11)
I see that the code gives me the expected result (the -2) but what I'm doing wrong regarding the methode that gives me this error
My code:
public class Evaluate {
static Stack<Character> ops = new Stack<Character>();
static Stack<Integer> vals = new Stack<Integer>();
static int i = 0;
public static void main(String[] args) {
System.out.println(parse("(4-(7-1))"));
System.out.println(parse("8"));
System.out.println(parse("((1+1)*(2*2))"));
System.out.print("\n");
System.out.println(parse("(6/(3/2))"));
}
private static int parse(String expression) {
char[] tokens = expression.toCharArray();
while (tokens.length > i) {
char s = tokens[i];
if (s == '(') {
ops.push(tokens[i]);
} else if (s == '+' || s == '-' || s == '*' || s == '/') {
while (!ops.empty() && hasPrecedence(tokens[i], ops.peek()))
vals.push(applyOp(ops.pop(), vals.pop(), vals.pop()));
ops.push(s);
} else if (s == ')') {
char op = ops.pop();
int v = vals.pop();
while (ops.peek() != '(')
vals.push(applyOp(ops.pop(), vals.pop(), vals.pop()));
ops.pop();
if (op == '+') {
v = vals.pop() + v;
} else if (op == '-') {
v = vals.pop() - v;
} else if (op == '*') {
v = vals.pop() * v;
} else if (op == '/') {
v = vals.pop() / v;
}
vals.push(v);
} else {
vals.push(Character.getNumericValue(s));
}
i++;
}
while (!ops.empty())
vals.push(applyOp(ops.pop(), vals.pop(), vals.pop()));
return vals.pop();
}
public static boolean hasPrecedence(char op1, char op2) {
if (op2 == '(' || op2 == ')')
return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
return false;
else
return true;
}
// A utility method to apply an
// operator 'op' on operands 'a'
// and 'b'. Return the result.
public static int applyOp(char op, int b, int a) {
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}

Infix to Postfix Java Algorithm Issue

So I was assigned to create an method which takes in a string in infix notation as a parameter and returns a string in postfix notation.
My code seems to work for most examples I throw at it, but a few inputs cause wacky results.
public class Operations<T> {
public int value(char c){
switch(c){
case '(':
case ')':
return 3;
case '*':
case '/':
case '%':
return 2;
case '+':
case '-':
return 1;
default:
return 0;
}
}
public String infixToPostfix(String infix){
//Operator stack
myStack<Character> ops = new myStack<Character>();
//Postfix string
String postfix = "";
//Current char being read
char c;
//Marks if paranthesis are being passed in
boolean flag = false;
//Iterate through each character to find operators
for(int i=0; i<infix.length(); i++){
c = infix.charAt(i);
//Add operand to postfix and operator to stack
if(value(c)==0){
postfix+=c;
} else if(ops.isEmpty() || (value(c)>value(ops.getTop()) && c!=')') || c=='(') {
ops.push(c);
} else if(value(c)<value(ops.getTop()) && c!=')') {
if(ops.getTop()=='(' || flag) {
ops.push(c);
flag = true;
} else {
postfix+=ops.pop();
while(!ops.isEmpty() && value(c)<value(ops.getTop())) {
postfix+=ops.pop();
}
ops.push(c);
}
} else if(c==')') {
while(ops.getTop()!='('){
postfix+=ops.pop();
}
ops.pop();
flag = false;
} else {
postfix+=ops.pop();
ops.push(c);
}
}
while(!ops.isEmpty()){
postfix+=ops.pop();
}
return postfix;
}
}
for example, the equation:
- A * B + (C/D*7) – ( (A%C-8) / (H+F-D))
outputs:
ABCD/7+AC8-%HF+D-/-
while the correct answer is:
ABCD/7+AC%8-HF+D-/
What is causing the problem? Thanks

Infix to Postfix using Stacks Java

I am trying to write a program to convert an infix expression to a postfix expression.
The algorithm that I am using is as follows :
1. Create a stack
2. For each character t in the expression
- If t is an operand, append it to the output
- Else if t is ')',then pop from the stack till '(' is encountered and append
it to the output. do not append '(' to the output.
- If t is an operator or '('
-- If t has higher precedence than the top of the stack, then push t
on to the stack.
-- If t has lower precedence than top of the stack, then keep popping
from the stack and appending to the output until either stack is
empty or a lower priority operator is encountered.
After the input is over, keep popping and appending to the output until the
stack is empty.
Here is my code which prints out wrong results.
public class InfixToPostfix
{
private static boolean isOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
|| c == '(' || c == ')';
}
private static boolean isLowerPrecedence(char op1, char op2)
{
switch (op1)
{
case '+':
case '-':
return !(op2 == '+' || op2 == '-');
case '*':
case '/':
return op2 == '^' || op2 == '(';
case '^':
return op2 == '(';
case '(':
return true;
default:
return false;
}
}
public static String convertToPostfix(String infix)
{
Stack<Character> stack = new Stack<Character>();
StringBuffer postfix = new StringBuffer(infix.length());
char c;
for (int i = 0; i < infix.length(); i++)
{
c = infix.charAt(i);
if (!isOperator(c))
{
postfix.append(c);
}
else
{
if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
postfix.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else
{
if (!stack.isEmpty() && !isLowerPrecedence(c, stack.peek()))
{
stack.push(c);
}
else
{
while (!stack.isEmpty() && isLowerPrecedence(c, stack.peek()))
{
Character pop = stack.pop();
if (pop != '(')
{
postfix.append(pop);
}
}
}
stack.push(c);
}
}
}
return postfix.toString();
}
public static void main(String[] args)
{
System.out.println(convertToPostfix("A*B-(C+D)+E"));
}
}
The program should print AB*CD+-E+ but it is printing AB*-CD+E.
Why is the output incorrect ?
Also, Is there a more elegant solution to this problem. Please share if you have or know one.
Issue is with your else part:
if (!stack.isEmpty() && !isLowerPrecedence(c, stack.peek()))
{
stack.push(c);
}
else
{
while (!stack.isEmpty() && isLowerPrecedence(c, stack.peek()))
{
Character pop = stack.pop();
if (pop != '(')
{
postfix.append(pop);
}
}
}
stack.push(c);
So here you are pushing the same c element twice with stack.push() when you see stack is not empty and precedence match is higher.
So put this stack.push within else part or remove the push from if condition.
Another issue is, when at the end you have some operators within the stack you dont pop them out.
Here's the code that i came up with for your case:
private static boolean isOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
|| c == '(' || c == ')';
}
private static boolean isLowerPrecedence(char op1, char op2)
{
switch (op1)
{
case '+':
case '-':
return !(op2 == '+' || op2 == '-');
case '*':
case '/':
return op2 == '^' || op2 == '(';
case '^':
return op2 == '(';
case '(':
return true;
default:
return false;
}
}
public static String convertToPostfix(String infix)
{
Stack<Character> stack = new Stack<Character>();
StringBuffer postfix = new StringBuffer(infix.length());
char c;
for (int i = 0; i < infix.length(); i++)
{
c = infix.charAt(i);
if (!isOperator(c))
{
postfix.append(c);
}
else
{
if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
postfix.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else
{
if (!stack.isEmpty() && !isLowerPrecedence(c, stack.peek()))
{
stack.push(c);
}
else
{
while (!stack.isEmpty() && isLowerPrecedence(c, stack.peek()))
{
Character pop = stack.pop();
if (c != '(')
{
postfix.append(pop);
} else {
c = pop;
}
}
stack.push(c);
}
}
}
}
while (!stack.isEmpty()) {
postfix.append(stack.pop());
}
return postfix.toString();
}
public static void main(String[] args)
{
System.out.println(convertToPostfix("A*B-(C+D)+E"));
}
I think above answer is not correct.
This is the version corrected by me :
package Stack;
import java.util.Stack;
/*
*
Algorithm
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
…..3.1 If the precedence of the scanned operator is greater than the precedence of the operator in the stack(or the stack is empty), push it.
…..3.2 Else, Pop the operator from the stack until the precedence of the scanned operator is less-equal to the precedence of the operator residing on the top of the stack. Push the scanned operator to the stack.
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop and output from the stack until an ‘(‘ is encountered.
6. Repeat steps 2-6 until infix expression is scanned.
7. Pop and output from the stack until it is not empty.
*/
public class InfixToPostFixEvalution {
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')';
}
private static int getPrecedence(char ch) {
switch (ch) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
// A utility function to check if the given character is operand
private static boolean isOperand(char ch) {
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}
public static String convertToPostfix(String infix) {
Stack<Character> stack = new Stack<Character>();
StringBuffer postfix = new StringBuffer(infix.length());
char c;
for (int i = 0; i < infix.length(); i++) {
c = infix.charAt(i);
if (isOperand(c)) {
postfix.append(c);
} else if (c == '(') {
stack.push(c);
}
// If the scanned character is an ‘)’, pop and output from the stack
// until an ‘(‘ is encountered.
else if (c == ')') {
while (!stack.isEmpty() && stack.peek() != '(') {
postfix.append(stack.pop());
}
if (!stack.isEmpty() && stack.peek() != '(')
return null;
else if(!stack.isEmpty())
stack.pop();
}
else if (isOperator(c)) // operator encountered
{
if (!stack.isEmpty() && getPrecedence(c) <= getPrecedence(stack.peek())) {
postfix.append(stack.pop());
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
postfix.append(stack.pop());
}
return postfix.toString();
}
public static void main(String[] args) {
System.out.println(convertToPostfix("a+b*(c^d-e)^(f+g*h)-i"));
}
}
This code inserts the "(" as well in stack and removes accordingly. Just another way of implementing infix to postfix. Here the check is until I do not find lower priority operator in stack I will pop out the value. e.g if stack has - and next operator is +, it will pop - as it is of equal priority.
I have added custom stack implementation, however normal stack provide by java can also be used in place
import chapter4.LinkedListStack(custom stack implementation);
public class InfixToPostfix {
public String infixToPostfix(String str) {
LinkedListStack<String> stack = new LinkedListStack<>();
String[] st = str.split("");
String result = "";
for (String s : st) {
if (operator(s)) {
if (")".equals(s)) {
while (!stack.isEmpty() && !"(".equals(stack.getTop())) {
result += stack.pop();
}
if (!stack.isEmpty()) {
stack.pop();
}
} else {
if (!stack.isEmpty() && !isLowerPrecedence(s, stack.getTop())) {
stack.push(s);
} else {
while (!stack.isEmpty() && isLowerPrecedence(s, stack.getTop())) {
String top = stack.pop();
if (!"(".equals(top)) {
result += top;
}
}
stack.push(s);
}
}
} else {
result += s;
}
}
while (!stack.isEmpty()) {
result += stack.pop();
}
return result;
}
private boolean isLowerPrecedence(String s, String s1) {
switch (s) {
case "+":
return !("+".equals(s1) || "(".equals(s1));
case "-":
return !("-".equals(s1) || "(".equals(s1));
case "*":
return "/".equals(s1) || "^".equals(s1) || "(".equals(s1);
case "/":
return "*".equals(s1) || "^".equals(s1) || "(".equals(s1);
case "^":
return "(".equals(s1);
case "(":
return false;
default:
return false;
}
}
private boolean operator(String s) {
return "+".equals(s) || "-".equals(s) || "*".equals(s) || "/".equals(s) || "^".equals(s) || "(".equals(s) ||
")".equals(s);
}
public static void main(String[] args) {
InfixToPostfix itp = new InfixToPostfix();
System.out.println("The Postfix expression for A*B-(C+D)+E is: " + itp.infixToPostfix("A*B-(C+D)+E"));
System.out.println("The Postfix expression for 1+2*4/5-7+3/6 is: " + itp.infixToPostfix("1+2*4/5-7+3/6"));
System.out.println("The Postfix expression for a+(b*c)/d is: " + itp.infixToPostfix("a+(b*c)/d"));
}
}
public class LinkedListStack<E> {
private Node<E> head;
private static class Node<E> {
E item;
Node<E> next;
public Node(E item, Node<E> next) {
this.item = item;
this.next = next;
}
}
public void push(E item) {
System.out.println("push: " + item);
Node<E> newNode = new Node<>(item, null);
newNode.next = head;
head = newNode;
}
public E pop() {
if (isEmpty()) {
System.out.println("stack is Empty -> empty stack exception");
return null;
}
System.out.println("pop: " + head.item);
E data = head.item;
head = head.next;
return data;
}
public boolean isEmpty() {
return head == null;
}
public E getTop() {
return head.item;
}
}
I think the problem is here:
private static boolean isLowerPrecedence(char op1, char op2)
{
switch (op1)
{
.....
case '(':
return true;
.....
}
In the case '(', false should be returned.
This solution requires proper braces around the original expression, but its quite simple and straight forward compared to other answers I looked at. Just for someone who might need it because the post is an old post.
public static String InfixToPostfix(String origin)
{
String[] params = origin.split(" ");
Stack<String> ops = new Stack<>();
Stack<String> vals = new Stack<>();
for (int i = 0; i < params.length; i++)
{
switch (params[i]) {
case "(":
;
break;
case "+":
ops.push(params[i]);
break;
case "-":
ops.push(params[i]);
break;
case "*":
ops.push(params[i]);
break;
case "/":
ops.push(params[i]);
break;
case "sqrt":
ops.push(params[i]);
break;
// Token not operator or paren: push double value.
case ")":
String d1 = vals.pop();
String d2 = vals.pop();
String op = ops.pop();
vals.push("( " + d2 + " " + d1 + " "+ op + " )");
break;
default:
vals.push(params[i]);
break;
}
}
// System.out.print(vals.pop());
return vals.pop();
}

java infix calculator

I cant seem to get the inside of the try block to make stacks, I am meant to get a calculator with single digit by using stacks inside the try block. The inside of the try block is giving me emptystackexception
import java.util.EmptyStackException;
import java.util.*;
public class Infix
{
public static void main(String[] args){
System.out.println(evaluateInfix("1*2*3"));
}
public static double evaluateInfix(String infix)
{
try
{
Stack<Character> valueStack = new Stack<Character> ();
Stack<Character> operatorStack = new Stack<Character> ();
double result;
for(char ch: infix.toCharArray()){
if(ch >= 0 && ch <= 9){
valueStack.push(ch);
} else if(ch == '('){
operatorStack.push(ch);
} else if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%' || ch == '^' || ch == '='){
if(operatorStack.isEmpty()){
operatorStack.push(ch);
} else if(precedence(ch) > precedence(operatorStack.peek())){
operatorStack.push(ch);
} else {
while(!operatorStack.isEmpty() && precedence(ch) <= precedence(operatorStack.peek())){
result = compute(valueOf(valueStack.pop()), valueOf(valueStack.pop()), operatorStack.pop());
valueStack.push((char)result);
}
operatorStack.push(ch);
}
} else if(ch == ')'){
while(operatorStack.peek() != '('){
result = compute(valueOf(valueStack.pop()), valueOf(valueStack.pop()), operatorStack.pop());
valueStack.push((char)result);
}
operatorStack.pop();
}
}
while(!operatorStack.isEmpty()){
result = compute(valueOf(valueStack.pop()), valueOf(valueStack.pop()), operatorStack.pop());
valueStack.push((char)result);
}
result = valueStack.peek();
System.out.println(result);
/* **********
Task 3
complete this section to calculate the infix expression
*/
} //end try
catch (EmptyStackException e)
{
/* **********
Task 3
complete this to return Double.NaN
*/
}
catch (ArithmeticException e)
{
/* **********
Task 3
complete this to return Double.NEGATIVE_INFINITY
*/
}
return 3.0;
} // end evaluateInfix
private static int precedence(char operator)
{
switch(operator){
case '(': case ')': return 0;
case '+': case '-': return 1;
case '*': case '/': case '%': return 2;
case '^': return 3;
case '=': return 4;
}
return -1;
}
private static double valueOf(char variable)
{
switch (variable)
{
case '1': return 1.0;
case '2': return 2.0;
case '3': return 3.0;
case '4': return 4.0;
case '5': return 5.0;
case '6': return 6.0;
case '7': return 7.0;
case '8': return 8.0;
case '9': return 9.0;
case '0': return 0.0;
} // end switch
return 0;
} // end valueOf
private static Double compute(Double operandOne, Double operandTwo, char operator)
{
if(operator == '+'){
return operandOne + operandTwo;
} else if(operator == '-'){
return operandOne - operandTwo;
} else if(operator == '*'){
return operandOne * operandTwo;
} else if(operator == '/'){
return operandOne / operandTwo;
} else if(operator == '%'){
return operandOne % operandTwo;
} else if(operator == '^'){
return Math.pow(operandOne, operandTwo);
} else {
return null;
}
} // end compute
} // end Infix
Shouldn't the first if contain '' around the numbers?
if(ch >= '0' && ch <= '9'){
You have a redundant pair of "}" and "{" which turn the bulk of your code into an initialization block - essentially a constructor of the Infix class.
(Based on your comment) - there is a missing method declaration.
Try changing the first few lines from:
public class Infix {
public static void main(String[] args){
System.out.println(evaluateInfix("1*2*3"));
}
{
try {
...
to:
public class Infix {
public static void main(String[] args){
System.out.println(evaluateInfix("1*2*3"));
}
public static double evaluateInfix(String infix) {
try {
...

How to calculate expression in java?

How to calculate user given Expression in java.
E:g, if the given exp is 3*4+(5*6)
how to calculate this. can anyone help me out.
I found this code after a quick google:
import java.util.Stack;
/**
* Class to evaluate infix and postfix expressions.
*
* #author Paul E. Davis (feedback#willcode4beer.com)
*/
public class InfixPostfixEvaluator {
/**
* Operators in reverse order of precedence.
*/
private static final String operators = "-+/*";
private static final String operands = "0123456789";
public int evalInfix(String infix) {
return evaluatePostfix(convert2Postfix(infix));
}
public String convert2Postfix(String infixExpr) {
char[] chars = infixExpr.toCharArray();
Stack<Character> stack = new Stack<Character>();
StringBuilder out = new StringBuilder(infixExpr.length());
for (char c : chars) {
if (isOperator(c)) {
while (!stack.isEmpty() && stack.peek() != '(') {
if (operatorGreaterOrEqual(stack.peek(), c)) {
out.append(stack.pop());
} else {
break;
}
}
stack.push(c);
} else if (c == '(') {
stack.push(c);
} else if (c == ')') {
while (!stack.isEmpty() && stack.peek() != '(') {
out.append(stack.pop());
}
if (!stack.isEmpty()) {
stack.pop();
}
} else if (isOperand(c)) {
out.append(c);
}
}
while (!stack.empty()) {
out.append(stack.pop());
}
return out.toString();
}
public int evaluatePostfix(String postfixExpr) {
char[] chars = postfixExpr.toCharArray();
Stack<Integer> stack = new Stack<Integer>();
for (char c : chars) {
if (isOperand(c)) {
stack.push(c - '0'); // convert char to int val
} else if (isOperator(c)) {
int op1 = stack.pop();
int op2 = stack.pop();
int result;
switch (c) {
case '*':
result = op1 * op2;
stack.push(result);
break;
case '/':
result = op2 / op1;
stack.push(result);
break;
case '+':
result = op1 + op2;
stack.push(result);
break;
case '-':
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}
private int getPrecedence(char operator) {
int ret = 0;
if (operator == '-' || operator == '+') {
ret = 1;
} else if (operator == '*' || operator == '/') {
ret = 2;
}
return ret;
}
private boolean operatorGreaterOrEqual(char op1, char op2) {
return getPrecedence(op1) >= getPrecedence(op2);
}
private boolean isOperator(char val) {
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val) {
return operands.indexOf(val) >= 0;
}
}
From: http://willcode4beer.com/design.jsp?set=evalInfix
Take a look at Java Expression evaluator: http://java.net/projects/eval/pages/Home
Java does this already. No need to download anything.
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class EvaluationExample {
public static void main(String[] args) throws Exception{
System.out.println(new ScriptEngineManager().getEngineByName("JavaScript").eval("3*4+(5*6)"));
}
}
(This is not the first SO answer to show how to use scripting in Java. I only added it here in case people looking at this page do not follow the links. Parsing is fun, and valuable to study, but if you just need to evaluate user-supplied expressions, use a script.)
UPDATE The OP is looking for a postfix evaluation solution. This has to be done in two steps: first convert the input string into postfix notation, then run the postfix "code" through a (presumably stack-based evaluator). See PaulPRO's answer for this. If you are willing to use JavaCC or another parser generator, you can be much more flexible with the strings you accept, allowing newlines and other whitespace.
Here's a spoiler (Mathematical Expression Parse in Java).

Categories

Resources