Я работаю над созданием калькулятора на основе пользовательского стекового класса, который использует простой 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 для стека значений.