Калькулятор стека не работает с круглыми скобками - PullRequest
0 голосов
/ 05 марта 2019

Я работаю над созданием калькулятора на основе пользовательского стекового класса, который использует простой ArrayList типа.У меня есть метод, который принимает входные данные с консоли и разделяется на различные части, чтобы они могли быть обработаны в операторы и операнды.Например: 2 + 4 + (6 - 2) будет разделен на "2", "+", "4", "+", "(", "6", "-", "2", ")"и сохранено в ArrayList.Я должен разделить стеки, один для всех операторов и один для всех значений.Мне удалось заставить работать все основные операции, но моя скобка не работает, когда я пытаюсь его обработать.

Это мой метод процесса со списком значений и операторов, сохраненных как переданный ArrayListв него, а также описание того, что должен делать правильно функционирующий алгоритм.

/**
 *  Evaluate expression and return the value
 *  @param tokens   a List of String tokens making up an arithmetic expression
 *  @return         a double value of the evaluated expression
 *  Algorithm:
 *  1. while there are tokens to be read in,
 *    1.1 Get the next token
 *    1.2 If the token is:
 *      1.2.1 A number: push it onto the value stack - COMPLETE
 *      1.2.2 (extra credit) A variable: get its value, and push onto the value stack
 *      1.2.3 A left parenthesis: push it onto the operator stack
 *      1.2.4 A right parenthesis
 *        A. While the thing on top of the operator stack is not
 *          a left parenthesis
 *          A.1 Pop the operator from the operator stack
 *          A.2 Pop the value stack twice, getting two operands.
 *          A.3 Apply the operator to the operands, in the correct order.
 *          A.4 Push the result onto the value stack.
 *        B. Pop the left parenthesis from the operator stack, and discard.
 *      1.2.5 An operator
 *        A. While the operator stack is not empty, and the top thing
 *          on the operator stack has the same or greater precedence
 *          as the token's operator (hasPrecedence below)
 *          A.1 Pop the operator from the operator stack
 *          A.2 Pop the value stack twice, getting two operands
 *          A.3 Apply the operator to the operands, in the correct order.
 *          A.4 Push the result onto the value stack.
 *        B. Push token operator onto the operator stack.
 *  2. While the operator stack is not empty,
 *      2.1 Pop the operator from the operator stack.
 *      2.2 Pop the value stack twice, getting two operands
 *      2.3 Apply the operator to the operands, in the correct order
 *      2.4 Push the result on the value stack.
 *  3. At this point the operator stack should be empty, and value stack
 *      should have only one value in it, which is the final result.
 */
public double evaluateExpression(List<String> tokens)
{
    double calculatedValue = 0;

    for(int i = 0; i < tokens.size(); i++)
    {
        char c = tokens.get(i).charAt(0);
        if(utils.isOperator(c))
        {
            if(c == '(')
            {
                operatorStack.push(tokens.get(i));
            }
            else if(c == ')')
            {
                while(operatorStack.peek().equals("(") == false)
                {
                    String operator = operatorStack.pop();
                    double val1 = valueStack.pop();
                    double val2 = valueStack.pop();
                    double result = doOperation(val2, operator, val1);
                    valueStack.push(result);
                }
            }
            else
            {
                while(operatorStack.isEmpty() == false && hasPrecedence(tokens.get(i), operatorStack.peek()))
                {
                    String operator = operatorStack.pop();
                    double val1 = valueStack.pop();
                    double val2 = valueStack.pop();
                    double result = doOperation(val2, operator, val1);
                    valueStack.push(result);
                }
                operatorStack.push(tokens.get(i));
            }
        }
        else
        {
            valueStack.push(Double.parseDouble(tokens.get(i)));
        }
    }

    while(!operatorStack.isEmpty())
    {
        double val1 = valueStack.pop();
        double val2 = valueStack.pop();
        String operation = operatorStack.pop();
        double result = doOperation(val2, operation, val1);
        valueStack.push(result);
    }
    return valueStack.pop();
}

Ошибка, которую я получаю, - это IndexOutOfBoundsException: -1 для стека значений.

...