Основная причина сбоя алгоритма заключается в использовании ==
при попытке проверки на равенство String
.
В Java ==
- логический оператор, который ведет себя одинаково для всех операндов, ипроверяет равенство значений операндов.Это означает, что примитивы проверяются, как и следовало ожидать, но строки, которые являются объектами, приведут к сравнению ссылок на память двух строк, что приведет к истине, только если две строки фактически являются одной и той же строкой.Это означает, что проверки на равенство строк должны выполняться с помощью метода equals
.
Существуют и другие проблемы с поведением калькулятора (алгоритмические), но их будет легче идентифицировать и исправить после обработки строки.проверки на равенство.Один пример проблемы, которая должна быть исправлена:
while(!ops.isEmpty() && nums.size() > 1)
{
String ab = ops.pop();
double bb = nums.pop();
double cb = nums.pop();
double clac = applyOperator(bb,ab,cb);
nums.add(clac);
}
Операнды (bb
и cb
) извлекаются из стека, поэтому они поступают в почтенном порядке (при разборе * 1014)* был помещен в стек до bb
).Это означает, что cb
- левый операнд, а bb
- правый операнд. -> double clac = applyOperator(cb,ab,bb);
Тот же рефакторинг должен быть выполнен для всех случаев использования метода applyOperand
.
Другая проблема заключается в следующем:
else if (prec(tokens [i]) < prec(ops.peek()) && !ops.isEmpty() && ops.peek() != "(")
{
String ac1 = ops.pop();
double res1 = nums.pop();
double res2 = nums.pop();
double outcome = applyOperator(res1,ac1,res2);
nums.add(outcome);
}
Была проведена внутренняя оценка, но запуск оценки - это обнаружение операнда с более низким присутствием.Операнд должен быть помещен в стек операций после оценки:
else if (prec(tokens [i]) < prec(ops.peek()) && !ops.isEmpty() && ops.peek() != "(")
{
...
...
nums.add(outcome); // I highly suggest refactoring this to nums.push due to readability considerations
ops.push(tokens[i]);
}
Ссылки: