HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Calculating infix expression with no parenthesis

Submitted by: @import:stackexchange-codereview··
0
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("*")) {

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:

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.