I'm having some issues making a recursive algorithm to be able to do some basic operations including multiplication, division, subtraction addition and power. I'm getting everything to work except when I start incorporating parentheses. I know for a fact that they take precedence but I'm not able to figure out how to do so.
The basic idea behind the code is to create a binary tree where each node is an operator start with the lowest precedence at the top and highest precedence at the bottom of the tree. My approach is to detect if there any closing parentheses first, check if there are any operators on the right of the closing parentheses, and if there is a valid operator, the left portion of the tree will be everything before the closing parentheses and the right portion of the tree will be everything after the operator. The problem I'm facing is when to consider the opening parenthesis...
Here's my code:
public static float eval(String exp) {
System.out.println(" \nNEW CALL STACK : " + exp);
float res = 0;
// if it starts with a negative
if(exp.startsWith("-")) {
return -1 * eval(exp.substring(1));
}
int opIndex = -1;
// start with closing paren
if (opIndex == -1) {
for (int i = exp.length() - 1; i >= 0; i--) {
if (exp.charAt(i) == ')') {
opIndex = i;
break;
}
}
}
if (opIndex == -1) {
for (int i = exp.length() - 1; i >= 0; i--) {
if (exp.charAt(i) == '+' || exp.charAt(i) == '-') {
opIndex = i;
break;
}
}
}
if (opIndex == -1) {
for (int i = exp.length() - 1; i >= 0; i--) {
if (exp.charAt(i) == '*' || exp.charAt(i) == '/') {
opIndex = i;
break;
}
}
}
if (opIndex == -1) {
for (int i = exp.length() - 1; i >= 0; i--) {
if (exp.charAt(i) == '^') {
opIndex = i;
break;
}
}
}
if (opIndex != -1) {
char operator = exp.charAt(opIndex);
String left = "";
String right = "";
// check to see if there's anything after the closing paren
if( operator == ')' && !exp.substring(opIndex+1, opIndex + 2).equals("")) {
left = exp.substring(0, opIndex);
operator = exp.charAt(opIndex+1);
right = exp.substring(opIndex+2);
} else {
left = exp.substring(0, opIndex); // left sub-tree
right= exp.substring(opIndex + 1, exp.length()); // right sub-tree
}
// operator is the "node"
System.out.println("Left: " + left + " operator: " + operator + " Right:" + right);
// start traversing
if (operator == '+') {
res = eval(left) + eval(right);
} else if (operator == '-') {
res = eval(left) - eval(right);
} else if (operator == '/') {
res = eval(left) / eval(right);
} else if( operator == '^') {
res = getPower( new Float (left), new Float( right) );
} else if( operator == '*') {
res = eval(left) * eval(right);
}
} else {
if(isNumber(exp)) return new Float(exp);
return 0;
}
return res;
}
Any tips or suggestions would be appreciated at this point.
EDIT
I'm not looking for built-in Java libraries to do this. I'm merely trying to figure out what I'm missing and where I'm going wrong.