В вашем коде есть несколько проблем:
Первая проблема - Вы не можете сравнить строку в java, используя операторы ==, которые вам нужны, и можете использовать такую функцию, как .equals () сравнить два строковых значения. Таким образом, код этого кода:
if (a == "0" || a == "1" || a == "2" || a == "3" ||a == "4" ||a == "5" ||
a == "6" ||a == "7" ||a == "8" ||a == "9")
изменяется на:
if (a.equals("0")|| a.equals("1") ||a.equals("2") || a.equals("3") ||a.equals("4") ||a.equals("5") ||
a.equals("6") ||a.equals("7") ||a.equals("8") ||a.equals("9"))
То же самое относится и к этой части фрагмента кода:
else if (a == "*" || a == "/" || a == "+" || a == "-")
, которую необходимо использовать В этом тоже есть функция .equals.
Та же проблема есть и в функции eval
в этой части:
if (r.left!=null && r.right!=null){
if (r.getOperator() == "+"){
return eval(r.left) + eval(r.right);
} else if (r.operator == "*"){
return eval(r.left) * eval(r.right);
} else if (r.operator == "/"){
return eval(r.left) / eval(r.right);
} else {
return eval(r.left) - eval(r.right);
}
} else {
return r.getOperand();
}
Вторая проблема - на входе expression
string ("34 2 - 5 *") одна из строк 34
, но она не будет удовлетворять этому условию:
if (a == "0" || a == "1" || a == "2" || a == "3" ||a == "4" ||a == "5" ||
a == "6" ||a == "7" ||a == "8" ||a == "9")
Таким образом, вместо проверки, является ли ваша строка номером или нет как вы можете создать вспомогательную функцию, чтобы сделать то же самое, как это, и вызвать то же самое:
private boolean checkStringIsNumber(String s) {
boolean numeric = true;
try {
Integer num = Integer.parseInt(s);
} catch (NumberFormatException e) {
numeric = false;
}
return numeric;
}
Третья проблема - в этих двух строках:
l.remove(l.size()-1);
l.remove(l.size()-2);
Предположим, Ваш список ссылок имеет два узла на данный момент. После l1, l2. После выполнения первого оператора
l.remove(l.size()-1);
обновленный список ссылок будет содержать один узел, т.е. l1. Теперь, если вы выполните эту инструкцию
l.remove(l.size()-2);
Она выдаст исключение, поскольку размер списка ссылок теперь равен 1, а l.size () - 2 вернется в -1, что является недопустимым индексом;
Итак, я полагаю, что вы хотите удалить последние 2 узла, чтобы вы могли сделать вместо этих двух операторов следующее:
l.remove(l.size()-1);
l.remove(l.size()-1);
Итак, после решения всех этих проблем обновил код конструктора ExpressionTree is:
public ExpressionTree(String expression){
LinkedList l = new LinkedList();
String[] s = expression.split(" ");
int i=0;
for (String a:s){
if (checkStringIsNumber(a)){
int b = Integer.parseInt(a);
ExpressionNode e = new ExpressionNode();
e.operand(b);
l.add(e);
}
else if (a.equals("*") || a.equals("/") || a.equals("+") || a.equals("-")){
ExpressionNode e = new ExpressionNode();
e.operator(a);
e.right = (ExpressionNode)l.get(l.size()-1);
e.left = (ExpressionNode)l.get(l.size()-2);
l.remove(l.size()-1);
l.remove(l.size()-1);
l.add(e);
}
}
root = (ExpressionNode)l.get(0);
}
и обновленный код функции eval is:
public int eval(ExpressionNode r){
if (r.left!=null && r.right!=null){
if (r.getOperator().equals("+")){
return eval(r.left) + eval(r.right);
} else if (r.operator.equals("*")){
return eval(r.left) * eval(r.right);
} else if (r.operator.equals("/")){
return eval(r.left) / eval(r.right);
} else {
return eval(r.left) - eval(r.right);
}
} else {
return r.getOperand();
}
}
После внесения этих изменений вышеприведенное выражение отлично работает и выдает результат как 160.