patternjavaMinor
Calculating infix expression with no parenthesis
Viewed 0 times
expressionwithinfixcalculatingparenthesis
Problem
This is my Java implementation (\$O(n)\$) about how to calculate infix expression with no parenthesis.
For example, when we input "3 + 4 * 4 / 8", we will get a double type answer is 5.0. Here to make the algorithm simple, we don't consider any parenthesis in the expression.
I think my implementation is kind of tedious and long. Can anyone give me some advice on making it cleaner?
```
public double computeInfixExpr(String input) {
String[] expr = input.split(" ");
int i = 0;
double operLeft = Integer.valueOf(expr[i++]);
while (i < expr.length) {
String operator = expr[i++];
double operRight = Double.valueOf(expr[i++]);
switch (operator) {
case "*":
operLeft = operLeft * operRight;
break;
case "/":
operLeft = operLeft / operRight;
break;
case "+":
while (i < expr.length) {
String operator2 = expr[i++];
if (operator2.equals("+") || operator2.equals("-")) {
i--;
break;
}
if (operator2.equals("*")) {
operRight = operRight * Double.valueOf(expr[i++]);
}
if (operator2.equals("/")) {
operRight = operRight / Double.valueOf(expr[i++]);
}
}
operLeft = operLeft + operRight;
break;
case "-":
while (i < expr.length) {
String operator2 = expr[i++];
if (operator2.equals("+") || operator2.equals("-")) {
i--;
break;
}
if (operator2.equals("*")) {
For example, when we input "3 + 4 * 4 / 8", we will get a double type answer is 5.0. Here to make the algorithm simple, we don't consider any parenthesis in the expression.
I think my implementation is kind of tedious and long. Can anyone give me some advice on making it cleaner?
```
public double computeInfixExpr(String input) {
String[] expr = input.split(" ");
int i = 0;
double operLeft = Integer.valueOf(expr[i++]);
while (i < expr.length) {
String operator = expr[i++];
double operRight = Double.valueOf(expr[i++]);
switch (operator) {
case "*":
operLeft = operLeft * operRight;
break;
case "/":
operLeft = operLeft / operRight;
break;
case "+":
while (i < expr.length) {
String operator2 = expr[i++];
if (operator2.equals("+") || operator2.equals("-")) {
i--;
break;
}
if (operator2.equals("*")) {
operRight = operRight * Double.valueOf(expr[i++]);
}
if (operator2.equals("/")) {
operRight = operRight / Double.valueOf(expr[i++]);
}
}
operLeft = operLeft + operRight;
break;
case "-":
while (i < expr.length) {
String operator2 = expr[i++];
if (operator2.equals("+") || operator2.equals("-")) {
i--;
break;
}
if (operator2.equals("*")) {
Solution
It is common, when processing things like this, to use a chain-of-responsibility pattern.
In this case, you can create an operator interface, or abstract class:
Then, you create an instance of that interface for each operator you support like the following for 'add':
Then, you create an instance for all your supported operators, and then put them in to an array, in precedence order (if you support precedence).
It will look like:
and, in your parsing/handling code, you do the following:
This will drastically simplify your code, and it will make it much easier to support other operations too.
In this case, you can create an operator interface, or abstract class:
public interface BinaryOperator {
public boolean isOwner(String operator);
public double operateOn(double left, double right);
}Then, you create an instance of that interface for each operator you support like the following for 'add':
public class AddOperator implements BinaryOperator {
public boolean isOwner(String op) {
return "+".equals(op);
}
public double operateOn(double left, double right) {
return left + right;
}
}Then, you create an instance for all your supported operators, and then put them in to an array, in precedence order (if you support precedence).
It will look like:
private static final BinaryOperator OPERATORS = {
new MultiplyOperator(),
....
new AddOperator(),
new SubtractOperator()
}and, in your parsing/handling code, you do the following:
public double handle(double left, String parsedOp, double right) {
for (BinaryOperator op : OPERATORS) {
if (op.isOwner(parsedOp)) {
return op.operateOn(left, right);
}
}
throw new UnsupportedOperationException("Can't handle " + parsedOp);
}This will drastically simplify your code, and it will make it much easier to support other operations too.
Code Snippets
public interface BinaryOperator {
public boolean isOwner(String operator);
public double operateOn(double left, double right);
}public class AddOperator implements BinaryOperator {
public boolean isOwner(String op) {
return "+".equals(op);
}
public double operateOn(double left, double right) {
return left + right;
}
}private static final BinaryOperator OPERATORS = {
new MultiplyOperator(),
....
new AddOperator(),
new SubtractOperator()
}public double handle(double left, String parsedOp, double right) {
for (BinaryOperator op : OPERATORS) {
if (op.isOwner(parsedOp)) {
return op.operateOn(left, right);
}
}
throw new UnsupportedOperationException("Can't handle " + parsedOp);
}Context
StackExchange Code Review Q#52130, answer score: 8
Revisions (0)
No revisions yet.