Java计算器崩溃与括号的输入

时间:2014-05-06 04:04:35

标签: java stack calculator

帮我堆栈溢出,你是我唯一的希望。我一直在努力制作一个简单的计算器,最后我已经开始工作了!问题是只评估表达式。例如:4 * 5将给出20.0。 (真棒!)

每当我给它一个更复杂的表达式如4 *(2 + 3)时,程序因EmptyStackException而崩溃。我理解异常,但是当我用脑子和一张纸手动完成代码时,我无法重新思考这个问题。

任何人都可以弄清楚它崩溃的原因吗?这是完整的代码。我用一些大胆的全文字标记了代码崩溃的地方。 (即程序崩溃)

/**
 * Human
 * Project 3: SUPER-DUPER JAVA CALCULATOR
 */

import java.util.*;
import java.util.Stack;
import java.lang.String;
import java.util.ArrayList;
import java.lang.StringBuilder;
import java.util.HashSet;
import java.lang.Exception;
import java.lang.Math;

public class InfixEvaluator {

    public static class SyntaxErrorException extends Exception {
        /**
         * Construct a SyntaxErrorException with the specified message.
         *
         * @param message The message
         */
        SyntaxErrorException(String message) {
            super(message);
        }
    }

    /**
     * This is the stack of operands:
     * i.e. (doubles/parentheses/brackets/curly braces)
     */
    private static Stack<Double> operandStack = new Stack<Double>();

    /**
     * This is the operator stack
     * i.e. (+-/*%^)
     */
    private static Stack<String> operatorStack = new Stack<String>();

    /**
     * These are the possible operators
     */
    private static final String OPERATORS = "+-/*%^()[]{}";
    private static final String BRACES = "()[]{}";
    private static final String NONBRACES = "+-/*%^";
    private static final int[] PRECEDENCE = {1, 1, 2, 2, 2, -1, -1, -1, -1, -1, -1};
    /**
     * This is an ArrayList of all the discrete
     * things (operators/operands) making up an input.
     * This is really just getting rid of the spaces,
     * and dividing up the "stuff" into manageable pieces.
     */
    static ArrayList<String> input = new ArrayList<String>();

    public static ArrayList inputCleaner(String postfix) {
        StringBuilder sb = new StringBuilder();
        String noSpaces = postfix.replace(" ", "");
        try {
            for (int i = 0; i < noSpaces.length(); i++) {
                char c = noSpaces.charAt(i);
                boolean isNum = (c >= '0' && c <= '9');

                if (isNum) {
                    sb.append(c);
                    if (i == noSpaces.length() - 1) {
                        input.add(sb.toString());
                        sb.delete(0, sb.length());
                    }
                } else if (c == '.') {
                    for (int j = 0; j < sb.length(); j++) {
                        if (sb.charAt(j) == '.') {
                            throw new SyntaxErrorException("You can't have two decimals in a number.");
                        } else if (j == sb.length() - 1) {
                            sb.append(c);
                            j = (sb.length() + 1);
                        }
                    }
                    if (sb.length() == 0) {
                        sb.append(c);
                    }
                    if (i == noSpaces.length() - 1) {
                        throw new SyntaxErrorException("You can't end your equation with a decimal!");
                    }
                } else if (OPERATORS.indexOf(c) != -1) {
                    if (sb.length() != 0) {
                        input.add(sb.toString());
                        sb.delete(0, sb.length());
                    }
                    sb.append(c);
                    input.add(sb.toString());
                    sb.delete(0, sb.length());
                } else {
                    throw new SyntaxErrorException("Make sure your input only contains numbers, operators, or parantheses/brackets/braces.");
                }
            }

            int numLP = 0;
            int numRP = 0;
            int numLB = 0;
            int numRB = 0;
            int numLBr = 0;
            int numRBr = 0;

            for (int f = 0; f < input.size(); f++) {
                String trololol = input.get(f);

                switch (trololol) {
                    case "(":
                        numLP++;
                        break;
                    case "[":
                        numLB++;
                        break;
                    case "{":
                        numLBr++;
                        break;
                    case ")":
                        numRP++;
                        break;
                    case "]":
                        numRB++;
                        break;
                    case "}":
                        numRBr++;
                        break;
                    default: //do nothing
                        break;
                }

            }
            if (numLP != numRP || numLB != numRB || numLBr != numRBr) {
                throw new SyntaxErrorException("The number of brackets, braces, or parentheses don't match up!");
            }

            int doop = 0;
            int scoop = 0;
            int foop = 0;
            for (int f = 0; f < input.size(); f++) {
                String awesome = input.get(f);
                switch (awesome) {
                    case "(":
                        doop++;
                        break;
                    case "[":
                        scoop++;
                        break;
                    case "{":
                        foop++;
                        break;
                    case ")":
                        doop--;
                        break;
                    case "]":
                        scoop--;
                        break;
                    case "}":
                        foop--;
                        break;
                    default: //do nothing
                        break;
                }
                if (doop < 0 || scoop < 0 || foop < 0) {
                    throw new SyntaxErrorException("The order of your parentheses, brackets, or braces is off.\nMake sure you open a set of parenthesis/brackets/braces before you close them.");
                }
            }
            if (NONBRACES.indexOf(input.get(input.size() - 1)) != -1) {
                throw new SyntaxErrorException("The input can't end in an operator");
            }
            return input;
        } catch (SyntaxErrorException ex) {
            System.out.println(ex);
            return input;
        }
    }

    /**
     * Method to process operators
     *
     * @param op The operator
     * @throws EmptyStackException
     */
    private static void processOperator(String op) {
        if (operatorStack.empty() || op == "(" || op == "[" || op == "{") {
            operatorStack.push(op);
        } else {
            //peek the operator stack and
            //let topOp be the top operator.
            String topOp = operatorStack.peek();
            if (precedence(op) > precedence(topOp)) {
                operatorStack.push(op);
            } else {
                //Pop all stacked operators with equal
                // or higher precedence than op.
                while (!operatorStack.empty() && precedence(op) <= precedence(topOp)) {
                    double r = operandStack.pop();
                    double l = operandStack.pop();
                    String work = operatorStack.pop();
                    switch (work) {
                        case "+":
                            operandStack.push(l + r);
                            break;
                        case "-":
                            operandStack.push(l - r);
                            break;
                        case "*":
                            operandStack.push(l * r);
                            break;
                        case "/":
                            operandStack.push(l / r);
                            break;
                        case "%":
                            operandStack.push(l % r);
                            break;
                        case "^":
                            operandStack.push(Math.pow(l, r));
                            break;
                        default: //do nothing, but this should never happen
                            break;
                    }

                    if (topOp == "(" || topOp == "[" || topOp == "{") {
                        //matching '(' popped - exit loop.
                        operandStack.push(l);
                        operandStack.push(r);
                        break;
                    }

                    if (!operatorStack.empty()) {
                        //reset topOp
                        topOp = operatorStack.peek();
                    }
                }

                //assert: Operator stack is empty or
                // current operator precedence > top of stack operator precedence.
                if (op != ")" || op != "]" || op != "}") {
                    operatorStack.push(op);
                }
            }
        }
    }

    public static String infixCalculator(ArrayList<String> puke) {
        int p;
        for (p = 0; p < puke.size(); p++) {
            if (OPERATORS.indexOf(puke.get(p)) == -1) {
                double herp = Double.parseDouble(puke.get(p));
                operandStack.push(herp);
            } else {
                processOperator(puke.get(p));
            }
        }
        if (p == puke.size()) {
            while (!operatorStack.empty()) {
                double r = operandStack.pop();
                double l = operandStack.pop();
                String work = operatorStack.pop();
                switch (work) {
                    case "+":
                        operandStack.push(l + r);
                        break;
                    case "-":
                        operandStack.push(l - r);
                        break;
                    case "*":
                        operandStack.push(l * r);
                        break;
                    case "/":
                        operandStack.push(l / r);
                        break;
                    case "%":
                        operandStack.push(l % r);
                        break;
                    case "^":
                        operandStack.push(Math.pow(l, r));
                        break;
                    default:
                        break;
                }
            }
        }
        return String.valueOf(operandStack.pop());
    }

    private static int precedence(String op) {
        return PRECEDENCE[OPERATORS.indexOf(op)];
    }

    public static void main(String[] args) {

        do {
            try {
                ArrayList test = new ArrayList();
                Scanner f = new Scanner(System.in);


                System.out.println("Please insert an argument: \n");


                String g = f.nextLine();

                test = inputCleaner(g);

                for (int z = 0; z < test.size(); z++) {
                    System.out.println(test.get(z));
                }

                System.out.println(infixCalculator(test));

                test.clear();
            } catch (EmptyStackException e) {
                System.out.println("Make sure you only put in operators and operands.");
            }
        } while (true);
    }
}

堆栈追踪:

java.util.EmptyStackException at 
    java.util.Stack.peek(Stack.java:102) at
    java.util.Stack.pop(Stack.java:84) at 
    InfixEvaluator.processOperator(InfixEvaluator.java:177) at 
    InfixEvaluator.infixCalculator(InfixEvaluator.java:225) at 
    InfixEvaluator.main(InfixEvaluator.java:276) 

2 个答案:

答案 0 :(得分:2)

当堆栈为空时,您的错误来自pop堆栈中的元素。因此名称为EmptyStackException

我注意到在你的循环中你会说while(!operatorStack.empty())之类的东西但是在while循环中你会弹出2个或者有时会从堆栈中弹出3个元素。如果你想从数组中弹出更多的元素而不是你应该在while循环中测试的元素。

因此,如果您关闭2个元素,请执行while (operatorStack.size() > 2 )。我编辑了你的代码,改变你所有的while循环是正确的,它适用于这些输入

(2+3)(2+3)+5

这是我做的:

  • 将样板代码移至新方法
  • 添加方法签名评论
  • 修正了运营商优先级,pow运营商的优先顺序错误。
  • 更改了从str1 == str2str1.equals(str2)的大量地方的字符串比较。你应该看看How do I compare strings in Java?,看看为什么我这样做。
  • System.out.println语句中添加以调试您的应用程序。我把它们留在了,所以你可以看到输出并亲自检查。您应该查看并查看我将来做了哪些工作来帮助您进行调试。

import java.util.*;
import java.util.Stack;
import java.lang.String;
import java.util.ArrayList;
import java.lang.StringBuilder;
import java.util.HashSet;
import java.lang.Exception;
import java.lang.Math;

public class InfixEvaluator
{

     public static class SyntaxErrorException extends Exception {
        /** Construct a SyntaxErrorException with the specified message.
           @param message The message
           */
        SyntaxErrorException(String message) {
            super(message);
        }
    }
    /** This is the stack of operands:
       i.e. (doubles/parentheses/brackets/curly braces)
    */
    private static Stack<Double> operandStack = new Stack<Double>();

    /** This is the operator stack
     *  i.e. (+-/*%^)
     */
    private static Stack<String> operatorStack = new Stack<String>();

    /** These are the possible operators */
    private static final String OPERATORS = "+-/*%^()[]{}";
    private static final String BRACES = "()[]{}";
    private static final String NONBRACES = "+-/*%^";
    //                                       +  -  /  *  %   ^  (   )   [   ]   {   }
    private static final int[] PRECEDENCE = {1, 1, 2, 2, 3, 3, -1, -1, -1, -1, -1, -1};
    /** This is an ArrayList of all the discrete
        things (operators/operands) making up an input.
        This is really just getting rid of the spaces,
        and dividing up the "stuff" into manageable pieces.
       */
    static ArrayList<String> input = new ArrayList<String>();

    /**
     * TODO: write this
     * @param postfix
     * @return
     */
    public static ArrayList inputCleaner(String postfix){
      StringBuilder sb = new StringBuilder();
      String noSpaces = postfix.replace(" ", "");
      try {
        for (int i = 0; i < noSpaces.length(); i++) {
            char c = noSpaces.charAt(i);
            boolean isNum = (c >= '0' && c <= '9');

            if (isNum) {
                sb.append(c);
                if (i == noSpaces.length()-1) {
                    input.add(sb.toString());
                    sb.delete(0, sb.length());
                }
            } else if (c == '.') {
                for (int j = 0; j < sb.length(); j++) {
                    if (sb.charAt(j) == '.') {
                        throw new SyntaxErrorException("You can't have two decimals in a number.");
                    } else if (j == sb.length() - 1) {
                        sb.append(c);
                        j = (sb.length() + 1);
                    } 
                } 
                if (sb.length() == 0) {
                    sb.append(c);
                }
                if (i == noSpaces.length()-1) {
                    throw new SyntaxErrorException("You can't end your equation with a decimal!");
                }
            } else if (OPERATORS.indexOf(c)!= -1) {
                if (sb.length() != 0) {
                    input.add(sb.toString());
                    sb.delete(0, sb.length()); 
                }
                sb.append(c);
                input.add(sb.toString());
                sb.delete(0, sb.length());
            } else {
                throw new SyntaxErrorException("Make sure your input only contains numbers, operators, or parantheses/brackets/braces.");
            }
        }

        int numLP = 0;
        int numRP = 0;
        int numLB = 0;
        int numRB = 0;
        int numLBr = 0;
        int numRBr = 0;

        for (int f = 0; f < input.size(); f++) {
            switch (input.get(f)) {
                case "(": numLP++;
                    break;
                case "[": numLB++;
                    break;
                case "{": numLBr++;
                    break;
                case ")": numRP++;
                    break;
                case "]": numRB++;
                    break;
                case "}": numRBr++;
                    break;
                default: //do nothing
                    break;
            }

        }
        if (numLP != numRP || numLB != numRB || numLBr != numRBr) {
            throw new SyntaxErrorException("The number of brackets, braces, or parentheses don't match up!");
        }

        int doop = 0;
        int scoop = 0;
        int foop = 0;
        for (int f = 0; f < input.size(); f++) {
            String awesome = input.get(f);
            switch (awesome) {
                case "(": doop++;
                    break;
                case "[": scoop++;
                    break;
                case "{": foop++;
                    break;
                case ")": doop--;
                    break;
                case "]": scoop--;
                    break;
                case "}": foop--;
                    break;
                default: //do nothing
                    break;
            }
            if (doop < 0 || scoop < 0 || foop < 0) {
                throw new SyntaxErrorException("The order of your parentheses, brackets, or braces is off.\nMake sure you open a set of parenthesis/brackets/braces before you close them.");
            }
        }
        if (NONBRACES.indexOf(input.get(input.size()-1)) != -1) {
            throw new SyntaxErrorException("The input can't end in an operator");
        }
        return input;
      } catch (SyntaxErrorException ex) {
            System.out.println(ex);
            return input;
      }
    }

     /**Method to process operators
     * @param op The operator
     * @throws SyntaxErrorException 
     * @throws EmptyStackException
     */
    private static void processOperator(String op) throws SyntaxErrorException {
        if (operatorStack.empty() || op.equals("(") || op.equals("[") || op.equals("{")) {
            operatorStack.push(op);
        } else {
            //peek the operator stack and
            //let topOp be the top operator.
            String topOp = operatorStack.peek();
            if (precedence(op) > precedence(topOp)) {
                topOp = op;
                operatorStack.push(op);
            } else {
                System.out.println(operatorStack);
                System.out.println(operandStack);
                System.out.println("--------------");
                //Pop all stacked operators with equal
                // or higher precedence than op.
                while (operandStack.size() >= 2 && !operatorStack.isEmpty()) {
                    double r = operandStack.pop();
                    double l = operandStack.pop();
                    String work = getNextNonBracerOperator();
                    System.out.println("L:" + l + " R:" + r + " W:" + work);

                    doOperandWork(work, l, r);

                    if(op.equals("(") || op.equals("[") || op.equals("{")) {
                        //matching '(' popped - exit loop.
                        operandStack.push(l);
                        operandStack.push(r);
                        break;
                    }

                    if (!operatorStack.empty()) {
                        //reset topOp
                        topOp = operatorStack.peek();
                    }
                }

                //assert: Operator stack is empty or
                // current operator precedence > top of stack operator precedence.
                if(!op.equals(")") || !op.equals("}") || !op.equals("}")) {
                    operatorStack.push(op);
                }
            }
        }
    }

    /**
     * TODO: write this
     * @param expressions
     * @return
     * @throws SyntaxErrorException
     */
    public static String infixCalculator(ArrayList<String> expressions) throws SyntaxErrorException {
        for (String expression : expressions) {
            if (OPERATORS.indexOf(expression) == -1) {
                operandStack.push(Double.parseDouble(expression));
            } else {
                processOperator(expression);
            } 
        } 
        while (operandStack.size() >= 2 && !operatorStack.isEmpty()) {
            System.out.println("--------------");
            System.out.println(operandStack);
            System.out.println(operatorStack);

            double r = operandStack.pop();
            double l = operandStack.pop();
            String work = getNextNonBracerOperator();
            System.out.println("L:" + l + " R:" + r + " W:" + work);

            doOperandWork(work, l, r);
        }
        if(operandStack.isEmpty())
            return null;
        return String.valueOf(operandStack.pop());
    }

    /**
     * goes through the stack and pops off all non operatable operations until it gets to one that is in the NONBRACES String
     * @return The next operatable string
     */
    private static String getNextNonBracerOperator() {
        String work = "\0"; // \0 is null, 
        while(!operatorStack.isEmpty() && NONBRACES.indexOf(work) == -1)
            work = operatorStack.pop();
        return work;
    }

    /**
     * 
     * @param work The operator you want to work. This really should be a character but its still a string
     * @param l Left side number
     * @param r Right side number
     * @throws SyntaxErrorException If the operator could not be found
     */
    private static void doOperandWork(String work, double l, double r) throws SyntaxErrorException {
        switch (work) {
            case "+": operandStack.push(l+r);
                break;
            case "-": operandStack.push(l-r);
                break;
            case "*": operandStack.push(l*r);
                break;
            case "/": operandStack.push(l/r);
                break;
            case "%": operandStack.push(l%r);
                break;
            case "^": operandStack.push(Math.pow(l, r));
                break;
            default: 
                throw new SyntaxErrorException("Invalid operand " + work);
        }
    }

    /**
     * @param op The operator
     * @return the precedence
     */
    private static int precedence(String op) {
        return PRECEDENCE[OPERATORS.indexOf(op)];
    }

    public static void main(String[] args) {
        try {
            ArrayList test = new ArrayList();
            Scanner f = new Scanner(System.in);

            //System.out.println("Please insert an argument: ");

            //String g = f.nextLine();
            //String g = "(1+1)^(3+1)";
            String g = "(1+3)*3^2+2*4-1";
            test = inputCleaner(g);

            for (int z = 0; z < test.size(); z++) {
                System.out.println(test.get(z));
            }

            System.out.println(infixCalculator(test));

            test.clear();
       } catch (SyntaxErrorException e) {
            System.out.println("Make sure you only put in operators and operands.");
            e.printStackTrace();
       }
    }
}

答案 1 :(得分:0)

您正在尝试将字符串与==进行比较。而是使用String.equals(String)

if(!op.equals(")") || !op.equals("]") || !op.equals("}")) {
   operatorStack.push(op);
}

...

if (operatorStack.empty() || op.equals("(") || op.equals("[") || op.equals("{")) {
   operatorStack.push(op);
} else {

...

if (topOp.equals("(") || topOp.equals("[") || topOp.equals("(")) {
  //matching '(' popped - exit loop.
  operandStack.push(l);
  operandStack.push(r);
  break;
}

如果您跟踪代码,您将看到您尝试使用"("作为运算符

在检查之前,您已经将")"推回到堆栈中。你应该进行检查。

if (precedence(op) > precedence(topOp)) {
   if(!op.equals(")") || !op.equals("]") || !op.equals("}")) {
     operatorStack.push(op);
   }
}

最终守则

import java.util.*;

public class InfixEvaluator
{

    public static void main(String[] args) {
    ArrayList test = new ArrayList();
    Scanner f = new Scanner(System.in);


    System.out.println("Please insert an argument: \n");

    String g = f.nextLine();

    test = inputCleaner(g);

    for (int z = 0; z < test.size(); z++) {
        System.out.println(test.get(z));
    }

    System.out.println(infixCalculator(test));
}


 public static class SyntaxErrorException extends Exception {
    /** Construct a SyntaxErrorException with the specified message.
       @param message The message
       */
    SyntaxErrorException(String message) {
        super(message);
    }
}
/** This is the stack of operands:
   i.e. (doubles/parentheses/brackets/curly braces)
*/
private static Stack<Double> operandStack = new Stack<Double>();

/** This is the operator stack
 *  i.e. (+-/*%^)
 */
private static Stack<String> operatorStack = new Stack<String>();

/** These are the possible operators */
private static final String OPERATORS = "+-/*%^()[]{}";
private static final String BRACES = "()[]{}";
private static final String NONBRACES = "+-/*%^";
private static final int[] PRECEDENCE = {1, 1, 2, 2, 2, -1, -1, -1, -1, -1, -1};
/** This is an ArrayList of all the discrete
    things (operators/operands) making up an input.
    This is really just getting rid of the spaces,
    and dividing up the "stuff" into manageable pieces.
   */
static ArrayList<String> input = new ArrayList<String>();

public static ArrayList inputCleaner(String postfix){
  StringBuilder poop = new StringBuilder();
  String doody = postfix.replace(" ", "");
  try {
    for (int i = 0; i < doody.length(); i++) {
        char c = doody.charAt(i);
        boolean isNum = (c >= '0' && c <= '9');

        if (isNum) {
            poop.append(c);
            if (i == doody.length()-1) {
                input.add(poop.toString());
                poop.delete(0, poop.length());
            }
        } else if (c == '.') {
            for (int j = 0; j < poop.length(); j++) {
                if (poop.charAt(j) == '.') {
                    throw new SyntaxErrorException("You can't have two decimals in a number.");
                } else if (j == poop.length() - 1) {
                    poop.append(c);
                    j = (poop.length() + 1);
                } 
            } 
            if (poop.length() == 0) {
                poop.append(c);
            }
            if (i == doody.length()-1) {
                throw new SyntaxErrorException("You can't end your equation with a decimal!");
            }
        } else if (OPERATORS.indexOf(c)!= -1) {
            if (poop.length() != 0) {
                input.add(poop.toString());
                poop.delete(0, poop.length()); 
            }
            poop.append(c);
            input.add(poop.toString());
            poop.delete(0, poop.length());
        } else {
            throw new SyntaxErrorException("Make sure your input only contains numbers, operators, or parantheses/brackets/braces.");
        }
    }

    int numLP = 0;
    int numRP = 0;
    int numLB = 0;
    int numRB = 0;
    int numLBr = 0;
    int numRBr = 0;

    for (int f = 0; f < input.size(); f++) {
        String trololol = input.get(f);

        switch (trololol) {
            case "(": numLP++;
                break;
            case "[": numLB++;
                break;
            case "{": numLBr++;
                break;
            case ")": numRP++;
                break;
            case "]": numRB++;
                break;
            case "}": numRBr++;
                break;
            default: //do nothing
                break;
        }

    }
    if (numLP != numRP || numLB != numRB || numLBr != numRBr) {
        throw new SyntaxErrorException("The number of brackets, braces, or parentheses don't match up!");
    }

    int doop = 0;
    int scoop = 0;
    int foop = 0;
    for (int f = 0; f < input.size(); f++) {
        String awesome = input.get(f);
        switch (awesome) {
            case "(": doop++;
                break;
            case "[": scoop++;
                break;
            case "{": foop++;
                break;
            case ")": doop--;
                break;
            case "]": scoop--;
                break;
            case "}": foop--;
                break;
            default: //do nothing
                break;
        }
        if (doop < 0 || scoop < 0 || foop < 0) {
            throw new SyntaxErrorException("The order of your parentheses, brackets, or braces is off.\nMake sure you open a set of parenthesis/brackets/braces before you close them.");
        }
    }
    if (NONBRACES.indexOf(input.get(input.size()-1)) != -1) {
        throw new SyntaxErrorException("The input can't end in an operator");
    }
    return input;
  } catch (SyntaxErrorException ex) {
        System.out.println(ex);
        return input;
  }
}

 /**Method to process operators
 * @param op The operator
 * @throws EmptyStackException
 */
private static void processOperator(String op) {
    if (operatorStack.empty() || op.equals("(") || op.equals("[") || op.equals("{")) {
        operatorStack.push(op);
    } else {
        //peek the operator stack and
        //let topOp be the top operator.
        String topOp = operatorStack.peek();
        if (precedence(op) > precedence(topOp)) {
           if(!op.equals(")") || !op.equals("]") || !op.equals("}")) {
                operatorStack.push(op);
            }
        }
        else {
            //Pop all stacked operators with equal
            // or higher precedence than op.
            while (!operatorStack.empty() && precedence(op) <= precedence(topOp)) {
                double r = operandStack.pop();
                double l = operandStack.pop(); //***THE PROGRAM CRASHES HERE***
                String work = operatorStack.pop();
                switch (work) {
                    case "+": operandStack.push(l+r);
                        break;
                    case "-": operandStack.push(l-r);
                        break;
                    case "*": operandStack.push(l*r);
                        break;
                    case "/": operandStack.push(l/r);
                        break;
                    case "%": operandStack.push(l%r);
                        break;
                    case "^": operandStack.push(Math.pow(l, r));
                        break;
                    default: //do nothing, but this should never happen
                        break;
                }

                if (topOp.equals("(") || topOp.equals("[") || topOp.equals("(")) {
                    //matching '(' popped - exit loop.
                    operandStack.push(l);
                    operandStack.push(r);
                    break;
                }

                if (!operatorStack.empty()) {
                    //reset topOp
                    topOp = operatorStack.peek();
                }
            }

            //assert: Operator stack is empty or
            // current operator precedence > top of stack operator precedence.

        }
    }
}

public static String infixCalculator(ArrayList<String> puke) {
    int p;
    for (p = 0; p < puke.size(); p++) {
        if (OPERATORS.indexOf(puke.get(p)) == -1) {
            double herp = Double.parseDouble(puke.get(p));
            operandStack.push(herp);
        } else {
            processOperator(puke.get(p));
        } 
    } 
    if (p == puke.size()) {
        while (!operatorStack.empty()) {
                double r = operandStack.pop();
                double l = operandStack.pop();
                String work = operatorStack.pop();
                switch (work) {
                    case "+": operandStack.push(l+r);
                        break;
                    case "-": operandStack.push(l-r);
                        break;
                    case "*": operandStack.push(l*r);
                        break;
                    case "/": operandStack.push(l/r);
                        break;
                    case "%": operandStack.push(l%r);
                        break;
                    case "^": operandStack.push(Math.pow(l, r));
                        break;
                    default: //do nothing, but this should never happen
                        break;
                }
        }
    }
    return String.valueOf(operandStack.pop());
}

private static int precedence(String op) {
    return PRECEDENCE[OPERATORS.indexOf(op)];
}


}